IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Non affichage du 1er caractère structure record


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 27
    Points : 22
    Points
    22
    Par défaut Non affichage du 1er caractère structure record
    Bonjour tous et toutes,

    Je rencontre lors de l'écriture d'une petite application simple, un problème d'affichage et/ou de lecture des caractères d'un champ 'string' d'une structure record..

    Le pire est que dans une application faite il y a quelque mois plus tôt, j'utilisais le même principe et je n'ai pas rencontré ce type d'anomalie...

    Voici donc l'extrait de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    Type
      TDataX = record
        Chaine      :  string[10];
        Number1   :  integer;
        Numberx4  :  array[1..4] of byte;
        UnKnown1, UnKnown2  : integer;
    end;
     
    var
       DataX : array[0..11] of TDataX;
     
    procedure Show_DataX(const Nr: byte);
    begin
      frmView.TxtDataX1.Text := DataX[Nr].Chaine;
     
     ... 
    end;
    Jusque là, rien de sorcier, mais dans la procédure 'Show_DataX', le composant TxtDataX1 m'affiche toujours le contenu du champ DataX[Nr].chaine amputé de son PREMIER caractére

    Bref si le contenu de ce champ est : Tartempion, bien que ce soit correctement enregistré dans le fichier comme Tartempion, la procédure m'affiche toujours artempion

    J'ai pensé un instant que la chose était due à la façon qu'a Delphi de stocker em RAM les shortstring, mais comme je le disais plus haut, une structure du même accabit fonctionne sans probléme dans une autre appli...

    J'ai comparé les codes des 2 routines, la façon de déclarer les record... Rien trouvé de bizarre !

    Bon ben si une bonne âme parmi vous a un début de piste... Ce serait sympa.. Moi en attendant je vais aller fumer..plutôt que de fumer tout court.



    Ci et à la revoyure.

  2. #2
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    je pense que le probleme viens au moment du remplissage du champ Chaine ...

    tu lis comment ? stream ? INI ?
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 27
    Points : 22
    Points
    22
    Par défaut
    Salut Docteur,

    Pour répondre à ta question, ce sont des fichiers en 'raw data' pourrait on dire. Ils n'ont pas été créé avec l'une des base de données traditionnelles que nous connaissons aujourd'hui... Un exemple précis, voici un dump des premiers 78 octets du fichiers - sachant qu'un enregistrement complet se compose de 26 données qui sont :

    10 x bytes = Nom (Bref une string)
    4 x bytes = Nombre 1
    4 X bytes = Nombre 2
    4 X bytes = Nombre 3
    4 X bytes = Nombre 4

    47 45 52 41 52 44 20 20 48 20 00 00 00 1C 00 00 0F 40 00 00 00 2C 00 00 02 B2 GERARD H .......@...,....
    20 20 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .......................................
    41 4C 42 45 52 54 20 42 20 20 00 00 00 04 00 00 01 27 00 00 00 08 00 00 00 C4 ALBERT B .......'........

    Un autre Dump sur un fichier enregistré avec Delphi donne ceci :

    01 00 07 45 4E 56 49 54 45 4C 20 53 41 52 4C 00 00 00 00 00 00 00 00 00 00 00 00 ...ENVITEL SARL............
    ......

    Bon que dans cet exemple la longueur des 2 champs 'string' soient différentes n'a pas d'importance.

    Ce que je constate c'est que Delphi en enregistrant ses données de type 'record' ajoute 3 octets AVANT chaque enregistrement (01 00 07) ... Le 1er semble être le Nr de l'enregistrement concerné, et pour les 2 autres, je cherche encore leur signification.

    Comme on peut le constater, ces octets additionnels - entre les enregistrements - sont absents dans la structure étrangère que je cherche à lire. Par conséquent, j'ai l'impression (étant donné que j'ai la preuve et la certitude que dans ce fichier, un enregistrement complet est sur 26 octets), qu'il va me falloir lire ces fichiers byte par byte, puis les réassembler comme il se doit pour les stocker dans les variables correspondantes...

    Ou alors quelqu'un a t-il une meilleure idée ?...

    Ci et A+

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    c'est 1 octet pour la longueur + 10 caractères

    c'est le même problème que dans le sujet "Case interger of - caractère en trop"
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 27
    Points : 22
    Points
    22
    Par défaut
    Salut ShaiLeTroll,

    Merci pour la réponse mais désolé cette solution n'est pas la bonne...j'ai modifié ma structure record comme suit :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Type
      TDataX = record
        Chaine      :  string[11];
        Number1   :  integer;
        Numberx4  :  array[1..4] of byte;
        UnKnown1, UnKnown2  : integer;
    end;
    et pour etre certain, j'ai testé avec des longueurs de string jusqu'à 15...et çà ne change rien. Mon 1er caractère fait de la résistance et ne veut pas s'afficher.

    De toute façon augmenter la largeur du champ string au delà des 10 caractères qui le constitue est idiot , puisque je vais ramasser dans ce champ string les valeurs - à partir du 11eme byte - qui on une autre signification et ne font de toute façon pas partie de la chaine alphanumérique.

    Je vais essayer la solution avec packed record...que je ne connais pas trop... pour voir si ca ammeliore les choses. En attendant mieux me suis arrangé avec ma bricole habituelle...C'est lourd et c'est précisement ce que je voulais éviter - ... mais bon ca roule cahin caha



    la voila :

    (Il va de soi que toutes les variables citées dans cet extrait ont été déclarées quelque part )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    procedure Get_UnknownDatas(const FileName: shortstring);
    var i, x, data, Halt, bx : byte;
        FSize : word;
        FichierX  : File of byte;
        Sx :  string[10];
        ValeurX, dataX : integer;
    begin
      if not FileExists(FileName) then exit;
        Assign(FichierX, FileName);
        Reset(FichierX);
        FSize := FileSize(FichierX);
        Halt := (FSize div 26);
        x := 1;
     try
      while x <= Halt do
        begin
          Sx := '';
          for i := 1 to 10 do
            begin
              Read(FichierX, data);
              Sx := Sx + Chr(data);
            end;
          XDatas[x].Nahme := Sx;
          ValeurX := 0;
          Read(FichierX, data);
          dataX := (data * 16777216);
          inc(ValeurX, dataX);
          Read(FichierX, data);
          dataX := (data * 65536);
          inc(ValeurX, dataX);
          Read(FichierX, data);
          dataX := (data * 256);
          inc(ValeurX, dataX);
          Read(FichierX, data);
          inc(ValeurX, data);
          inc(x);
        end;
      finally
        CloseFile(FichierX);
      end;
      SwapIndian(ValeurX);
       Show_UnknownDatas(1);
    end;
    PS : un grand merci également à Montor (membre de ces forums) pour sa routine de convertion big endian <--> little endian sans laquelle j'aurais fini à l'asile

    Quoique .... Allez...

    A +++

  6. #6
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Type
      TDataX = record
        Chaine    : array[0..9] of char;
        Number1   : integer;
        Numberx4  : record case integer of
          0:(Bits : array[0..3] of byte);
          1:(Long : integer);
        end;
        UnKnown1, 
        UnKnown2  : integer;
      end;
    et pense à utiliser les stream, ou l'unité FView (FileView) que j'ai fais pour une précédente question du forum :
    Fichiers attachés Fichiers attachés
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 27
    Points : 22
    Points
    22
    Par défaut
    Ok Docteur,

    Merci...Je télécharge, je mets en chantier, je torture et je te dis si le patient est toujours vivant ....

    A +++

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par zano42 Voir le message
    Salut ShaiLeTroll,

    Merci pour la réponse mais désolé cette solution n'est pas la bonne...j'ai modifié ma structure record comme suit :
    Ben tout à fait normal, tu n'as pas compris ma réponse, tu n'as même pas lu l'aide sur le type "Chaine Courte", je ne disais pas qu'il fallait mettre 11 caractères, mais que ta chaine "String[10]" occupait 11 octets, le 1er pour sa longueur de 0 à 255 et derrière les 10 caractères ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Salut
    @Who tu as oublier la directive packed la taille de ta structure est 28 octects
    @ShaiLeTroll
    les chaines longues commençent aussi par indice 1, c'est pour rester en compatibilité avec ce type
    @zano42
    je ne pense pas que tu es besoin de la fonction swapindian mais c'est ta façon de lire le ficier n'est pas la bonne.
    essaie j'ai pas tout testé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    type
        TDataX = packed record
        Chaine    : array[0..9] of char;
        Number1,
        Numberx4,
        UnKnown1,
        UnKnown2  : integer;
      end;
     
    procedure Get_UnknownDatas(const FileName: string);
    const  BUFSIZE =SizeOf(TDataX);
    var
      i    :integer;
      Data :TDataX;
    begin
        if not FileExists(FileName) then Exit;
        with TFileStream.Create(FileName, fmOpenReadWrite) do
        try
            Position := 0;
            for i := 0 to (Size div BUFSIZE)-1 do
            begin
                  Read(Data,BUFSIZE);
     
                  {traitement ici }
            end;
        finally
          Free();
        end;
    end;

  10. #10
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Citation Envoyé par Montor Voir le message
    @ShaiLeTroll
    les chaines longues commençent aussi par indice 1, c'est pour rester en compatibilité avec ce type
    Shai a simplement dit qu'une chaine courte, string[10] dans l'exemple, était codé sur 11 octets et que S[0] contenait la longueur de la chaine. Tout simplement.
    Répondant ainsi à la question de Zano sur la longueur de son record.

    @+

  11. #11
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    j'ai simplement conformer ses dires

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 27
    Points : 22
    Points
    22
    Par défaut
    salut a tous et toutes,

    Tout d'abord un grand MERCI aux contributeurs de ce post qui me permettront - grâce à leur conseils et propositions - de trouver enfin ce soir un sommeil réparateur (à moins que ce soit Madame qui soit contente )...

    La solution de MONTOR fonctionne comme papa dans maman et elle est déjà en service

    Merci aussi à Dr Who pour son Unité FileView qui me servira dans pas longtemps dans une autre appli...Eh..sans déconner ton truc est vraiment super

    J'avais oublié MONTOR de mentionner que les fichiers que je dois lire on été généré sur un système basé sur des Motorola,... Alors big endian, little endian : voyez ce que je veux dire

    En tout cas le problème est résolu, et comme toujours sur ce forum d'une façon prompte et précise... Encore bravo et Merci...Je laisse encore ce post ouvert quelques jours si quelqu'un veut y ajouter quelque chose et le fermerais sous peu.

    Sinon pour moi la chose est RESOLUE

    A la revoyure....

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [RegEx] Récupérer le 1er caractère non-html
    Par Xenon03 dans le forum Langage
    Réponses: 6
    Dernier message: 21/10/2010, 20h37
  2. Réponses: 11
    Dernier message: 05/04/2009, 11h31
  3. [ structure ] record et evolution
    Par petitcoucou31 dans le forum Langage
    Réponses: 15
    Dernier message: 29/10/2005, 01h36
  4. Affichage chaîne de caractère
    Par log2n dans le forum Assembleur
    Réponses: 1
    Dernier message: 25/10/2005, 22h41
  5. Réponses: 6
    Dernier message: 19/10/2004, 13h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo