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 :

affectation String et Record


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Par défaut affectation String et Record
    Bonjour,

    Je souhaite lire un fichier texte dont les lignes peuvent correspondre à 2 structures différentes:

    Exemple:
    NO REFART 00125Designation
    OR REFART Motif refus

    Les 2 premiers char de ligne permettent d'identifier sa structure.

    J'ai déclaré :

    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
      TStruc_no = record
            type : string[3]
            Ref : string[11]
            Qty : string[5]
            Des : string[50]
         end;
     
      TStruc_or = record
            type : string[3]
            Ref : string[11]
            Motif : string[150]
         end;
     
    Var
       ligne_no : TStruc_no;
       ligne_or : Tstruc_or;
       ligne : string;

    Dans mon code je voudrais faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //code
      Readln(fichier,ligne);
      if (copy(ligne,1,2) = 'NO')
        then ligne_NO := ligne;
     
      if (copy(ligne,1,2) = 'OR')
        then ligne_OR := ligne;
    mais ça ne fonctionne pas.

    Idem pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    //code
      ligne := ligne_NO;
      wrtieln(fichier,ligne);
    Comment dois je faire ?

    Par avance merci.

    Jérôme

  2. #2
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 542
    Billets dans le blog
    10
    Par défaut
    Tu devrais avoir plutôt les infos suivantes :
    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
    type
      TStruc_no = record
        type1 : string[3];
        Ref : string[11] ;
        Qty : string[5]  ;
        Des : string[50] ;
       end;
     
      TStruc_or = record
        type1 : string[3] ;
        Ref : string[11]  ;
        Motif : string[150] ;
      end;
     
    Var
    ligne_no : TStruc_no;
    ligne_or : Tstruc_or;
    ligne : string;
     
    begin
     
    ligne := 'AMKmlkmlkml' ;
    if (copy(ligne,1,2) = 'NO')
      then ligne_NO.type1 := copy(ligne,1,3)
     
    ....

  3. #3
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut
    Soit l'exemple que tu fournis est faux, soit tu as une erreur dans ton code

    car la Ref que tu montres, n'a que 7 caractères maximum et toi tu indiques 11 dans la Ref.

    Sinon, le mieux serait peut être de diviser en deux ton fonctionnement.
    et de faire 3 types au lieu de 2.

    On remarque que dans les 2 structures tu as des données communes donc pourquoi ne pas faire un type commun

    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
     
    Type Struc_Common = record
      Type : String[3];
      Ref : String[11];
    end;
     
    Type
      Struc_no = record
            Qty : string[5]
            Des : string[50]
         end;
     
      Struc_or = record
            Motif : string[150]
      end;
    Après tu n'as plus qu'a lire tes lignes en plusieurs fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    var
      Common : Struc_Common
      ligne_NO : Struc_no
      ligne_OR :Struc_or
    begin
      Read(fichier,Common);
      if trim(Common.Type) = 'NO' then
        Read(Fichier,Ligne_NO)
      else
        Read(Fichier,Ligne_OR);
    end;
    Bien sur c'est à tester et à adapter ^^
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Par défaut
    désolé, mais je ne suis pas.

    je viens de faire :

    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
    Type
      Struc_Common = record
          Typ : String[3];
          Ref : String[11];
        end;
    
      Struc_no = record
            Qty : string[5];
            Des : string[50];
         end;
    
      Struc_or = record
            Motif : string[150];
         end;
    
    const
      monfichier = 'd:\ess.txt';
    var
      Form1: TForm1;
      fichier : file of Struc_Common;
      Common : Struc_Common;
      ligne_NO : Struc_no;
      ligne_OR :Struc_or;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      assignfile(fichier, monfichier);
      reset(fichier);
      read(fichier,common);
    
      if trim(Common.Typ) = 'NO' then
        Read(Fichier,Ligne_NO)
      else
        Read(Fichier,Ligne_OR);
    
      close(fichier);
    end;
    et la compil plante comme dans mes essais précédents :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        Read(Fichier,Ligne_NO)
        Read(Fichier,Ligne_OR);
    Types incompatibles Struc_Common et Struc_No

  5. #5
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 542
    Billets dans le blog
    10
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
      assignfile(fichier, monfichier);
      reset(fichier);
      read(fichier,common);
     
      if trim(Common.Typ) = 'NO' then
        Read(Fichier,Ligne_NO)
      else
        Read(Fichier,Ligne_OR);
     
      close(fichier);
    C'est normal que ça plante ! La structure Record que tu utilise est une suite de strings et non pas un découpage d'une seule chaine. Donc tu ne coupes pas aux copy pour découper ta chaîne. Ceci-dit moi-je ferais peut être différement. Donne moi le nombre de lignes par fichier et je te donnerai une solution

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Par défaut
    dans mon prog final, j'aurais 5 structures différentes avec 30 à 40 fields / structures.
    Dans mon fichier en lecture j'aurais de 1 à x lignes.

    Donc je dois bien passer par une découpe de ma chaînes.

    Merci quand même

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 089
    Par défaut
    Ah la lecture de fichier structuré, ma spécialité !

    La Découpe peut-être entièrement géré par structure, j'ai déjà mis un exemple de code à ce sujet pour les Fichiers NX (CCAM), où il y a environ 200 type de ligne différent avec une dizaine de champ en moyenne, ...

    Les Lignes sont-elles complètes ?
    Par Exemple une ligne NO fait toujours 69 de longueur (complèté par des espaces par exemple) ou est-ce des longueurs variables ?

    le problème d'utiliser des ShortString dans les structures ajoute un octet pour la longueur, de plus, il vaut mieux ajouter la directive packed pour éviter des alignements processeurs ... même si avec le ShortString cela ne devrait pas arriver

    Pour le moment, je ne donnerais pas d'exemple, mais sinon je suis pour le moment assez d'accord avec Malatar, mais il faut pour que cela fonctionne des lignes à structure fixe ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Type
      Struc_Common = packed record
          Typ : Array[1..3] of Char;
          Ref : Array[1..11] of Char;
        end;
     
      Struc_no = packed record
            Qty : Array[5] of Char;
            Des : Array[50] of Char;
     
         end;
    le Array of Char, normalement, se lit facilement comme une chaine, il est possible de faire "Typ = 'OR'" ou même le passer à une fonction "StrToInt(Qty)"

    pour l'écriture c'est un peu plus problématique mais cela se résoud

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    StringToArrayOfChar('Salut', @ligne_NO.Des[1], Length(ligne_NO.Des));
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    StringToArrayOfChar(PChar(AString), @ligne_NO.Des[1], Length(ligne_NO.Des));

    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
    procedure StringToArrayOfChar(const S: string; const AoC: PChar; const LengthAoC: Integer);
    var
      LengthS: Integer;
    begin
      if LengthAoC <= 0 then
        Exit;
     
      LengthS := Length(S);
      if LengthS < LengthAoC then
      begin
        ZeroMemory(Pointer(Integer(AoC) + LengthS), LengthAoC - LengthS);
        CopyMemory(AoC, @S[1], LengthS);
      end else
      begin
        StrLCopy(AoC, @S[1], LengthAoC);
      end;
    end;
    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

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 16
    Par défaut
    Oui effectivement, je viens de corriger mes erreurs de frappe

    tu m'indiques de faire :

    ligne_NO.type1 := copy(ligne,1,3)

    Mais je voudrais éviter de faire :

    ligne_NO.type := copy(ligne,1,3);
    ligne_NO.Ref := copy(ligne,4,11);
    ligne_NO.Qty := copy(ligne,15,5);
    ....


    J'ai en réalité beaucoup de fields, donc je souhaiterais affecter la ligne à la structure.

    Est-il possible de faire un

    ligne_no := ligne; ?

    pour ensuite pouvoir exploiter les éléments de la structure.

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

Discussions similaires

  1. affecter string par char[]
    Par salihovic dans le forum Débuter
    Réponses: 8
    Dernier message: 08/05/2009, 16h15
  2. Affectation de String dans un tableau ?
    Par debie1108 dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 08/11/2006, 09h19
  3. [VB.NET]SourceGrid et affectation de valeurs dans une String
    Par Bourbaky dans le forum Windows Forms
    Réponses: 1
    Dernier message: 01/03/2006, 20h41
  4. Réponses: 2
    Dernier message: 27/01/2006, 16h47
  5. affecter l' hexa d'un nombre a un string
    Par sorari dans le forum SL & STL
    Réponses: 2
    Dernier message: 12/05/2005, 14h50

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