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

Delphi Discussion :

Structurer un fichier texte


Sujet :

Delphi

  1. #1
    Membre confirmé Avatar de cantador
    Homme Profil pro
    Chef de projet
    Inscrit en
    Mars 2006
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2006
    Messages : 569
    Points : 484
    Points
    484
    Par défaut Structurer un fichier texte
    Bonjour,

    j'ai un gros fichier texte constitué de blocs avec des titres.
    une structure hiérarchique en quelque sorte :

    TITRE0
    Sous-titre 0
    ligne0
    ligne1
    ligne2
    etc.
    Sous-titre 1
    ligne0
    ligne1
    ligne2
    ligne3
    etc.
    Sous-titre 2
    ligne0
    ligne1
    ligne2
    ligne3
    etc.
    TITRE1
    Sous-titre 0
    ligne0
    ligne1
    ligne2
    etc.
    etc..

    tout est variable, le nombre de titres, de sous-titres et de lignes.

    je souhaiterai reprendre ce fichier (ou simplement le lire) et placer le tout dans une structure permettant
    de lire un sous-titre avec ses lignes et selon les informations contenues y affecter une propriété booléenne (vrai ou faux)

    Ensuite, relire soit les blocs vrai, soir les blocs faux

    ça paraît simple à première vue, mais..
    j'ai testé pas mal de codes (array of array of TStringList) ou TRecord
    mais, ça ne colle pas vraiment..

    Donc, merci de me donner une piste de travail

    cordialement

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Qu'est ce qui permet de distinguer les sous-titres ?

  3. #3
    Membre actif
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Décembre 2014
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : Décembre 2014
    Messages : 105
    Points : 235
    Points
    235
    Par défaut
    Salut Cantador
    Ton truc me plait bien, laisse mais regarder, j'ai un peu de temps ce soir,
    Ah une question sur ta structure:
    Ta structure est-elle toujours avec 3 niveaux (Titre, Sous-titre, Ligne)
    ou bien ca peut-être avec plus de niveaux, du genre

    TITRE0
    Ligne 1
    Ligne ...
    S-titre 1
    Ligne 1
    Ligne 2
    Ligne ...
    S-Titre 2
    S-S-Titre 1
    Ligne 1
    Ligne ...
    S-S-Titre 2
    S-S-S-Titre 1
    Ligne ...
    3 niveaux ou n niveaux ?
    a toute

    solilog

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    est-il possible de transformer en XML ce serait plus simple en tout cas cela répondrai à tous tes objectifs
    je ne suis pas très doué (même pas du tout, en général je les lis ou les génère) en XML mais la structure devrait à peu près avoir la structure suivante

    <?xml version="1.0" encoding="UTF-8"?>
    <Fichier nom="Fichier.txt">
    <Titre intitulé="TITRE0">
    <Section nom="Section 0 " visible="Oui" >
    <Lignes>
    <ligne>ligne0</ligne>
    <ligne>ligne1</ligne>
    <ligne >ligne2</ligne>
    <ligne>ligne3</ligne>
    <ligne >ligne4</ligne>
    </Lignes>
    </Section>
    <Section nom="Section 1 " visible="Non" >
    <Lignes>
    <ligne>ligne0</ligne>
    <ligne>ligne1</ligne>
    </Lignes>
    </Section>
    ..
    </Titre>
    </Fichier>
    Note : j'ai utilisé cet utilitaire xml-copy-editor, pas sur que <Lignes> soit nécessaire

    sinon, même question que Selzig qu'est-ce qui permet de distinguer les "rubriques" , des espaces ou autres caractères devant que tu nous aurais caché?
    le fait que le premier niveau est tout en MAJ, le second avec une MAJ au début et les autres en minuscule serait-il un critère de choix ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Membre confirmé Avatar de cantador
    Homme Profil pro
    Chef de projet
    Inscrit en
    Mars 2006
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2006
    Messages : 569
    Points : 484
    Points
    484
    Par défaut suite..
    Bonjour,

    merci à tous !

    j'ai oublié de vous préciser un point :
    chaque sous-titre comporte en début de ligne un texte qui varie selon trois formules possibles.
    En clair, on est donc en mesure de trouver le début de chaque bloc et sa fin (avec un compteur)
    il reste à pouvoir stocker l'ensemble des blocs sous l'étiquette de son TITRE.
    bref, faire un structure à TROIS niveaux. (TITRE / SOUS-TITRE / BLOC DE LIGNES)
    chaque titre peut avoir plusieurs sous-titres, et chaque sous-titre peut comporter n lignes.
    Il n'y a pas de sous sous-titres (ouf..)
    je pourrais bien sûr faire des tables avec des relations, mais cela me semble lourd pour une utilisation hebdomadaire.
    j'aimerai plutôt construire un algo, qui range le tout dans des tableaux ou des StringList et ensuite pouvoir aller lire ce que je veux.

    merci pour vos suggestions

    cordialement

  6. #6
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    Février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bonjour Cantador.

    Apparemment, tu peux distinguer un titre d'un sous-titre...
    Je te suggère l'utilisation d'un seul TStringList, une ligne par sous-titre, en utilisant un séparateur (Alt 124 par exemple).
    Chaque ligne aurait donc la structure suivante :

    Titre0|Sous-titre0|true|ligne1|ligne2|ligne3|...
    Titre0|Sous-titre1|false|ligne1|ligne2|ligne3|...
    Titre0|Sous-titre2|true|ligne1|ligne2|ligne3|...
    Titre1|Sous-titre0|true|ligne1|ligne2|ligne3|...
    ...

    Il te suffit alors d'écrire une fonction de recherche d'un "champ", par exemple avec les fonctions Pos et PosEx du séparateur. (Champ 0 = titre, Champ1 = sous-titre...)
    Pour la recherche :
    - trouver la première ligne du StringList dont le champ 0 contient le titre souhaité.
    - lire toutes les lignes du StringList concernant ce titre jusqu'à trouver la ligne contenant le bon sous-titre.
    - lire et/ou modifier le champ boolean
    - lire le reste de la ligne du StringList (ligne1, ligne2...)

    Tu parles d'un gros fichier texte. Voir si cela reste dans les limites d'un StringList qui, si ma mémoire est bonne, correspond à la taille maximale d'une variable string.
    Sinon, utiliser un TList avec chaque item pointant sur une variable string.

    Cordialement
    Thierry

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    Il nous faudrait un extrait réel de ton fichier pour nous aider à t'aider.
    Et quitte à utiliser un fichier texte, je passerais plutôt par le format JSON.

  8. #8
    Membre confirmé Avatar de cantador
    Homme Profil pro
    Chef de projet
    Inscrit en
    Mars 2006
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2006
    Messages : 569
    Points : 484
    Points
    484
    Par défaut du code..
    Bonjour,

    j'ai commencé à travailler le code :

    Une précision, les débuts des lignes de TITRE comporte un texte commun (4 caractères) ->>> que je stocke dans stocode
    et le fichier est beaucoup plus court que prévu (1500 lignes environ)..

    voilà une solution fait à l'arrache, très mal écrite, mais qui marche :

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
     
    ...
    var
    TBLOC : array of TStringList;
    ...
     
    procedure CreateBloc(param: string; inc: integer);
    begin
      TBLOC[inc] := TStringList.Create;
      TBLOC[inc].Add(param);
    end;
     
    procedure TForm1.Button3Click(Sender: TObject);
    var
      SL: TStringList;
      i, co, cp: integer;
      stocode: string;
    begin
      SL := TStringList.Create;
      SL.LoadFromFile('MonFichier.csv');
     
      Finalize(TBLOC);
      SetLength(TBLOC, 1500);
     
      cp := 0;
      co := 0;
     
      for i := 0 to (SL.Count - 1) do
      begin
        if i = 0 then continue;
     
        if copy(SL.Strings[i], 1, 4) = stocode then
          stocode := SL.Strings[i];
     
        if (copy(SL.Strings[i], 1, 1) = 'A') or
          (copy(SL.Strings[i], 1, 1) = 'B') or
          (copy(SL.Strings[i], 1, 1) = 'C') then
        begin
          Inc(cp);
     
          if (cp mod 2 = 0) then
          begin
            Inc(co);
            CreateBloc(stocode, co);
            TBLOC[co].Add(SL.Strings[i]);
            cp := 1;
          end
          else
          begin
            CreateBloc(stocode, co);
            TBLOC[co].Add(SL.Strings[i]);
          end;
        end
        else
          if cp = 1 then
            TBLOC[co].Add(SL.Strings[i]);
      end;
     
      SetLength(TBLOC, co + 1);
     
    // pour tester le dernier
      for i := 0 to TBLOC[1371].Count - 1 do
        Memo4.Lines.Add(TBLOC[1371].strings[i]);
     
      for i := 0 to Length(TBLOC) - 1 do
        TBLOC[i].Free;
     
      SL.Free;
    end;
    Si vous avez une solution mieux ficelée..
    on aura réussi la première étape.
    encore que je me demande si on ne pourrai pas en profiter à la lecture des lignes d'un bloc
    pour stocker en fin de bloc, le code vrai/faux

    l'information de ce test consiste à tester deux informations (info1 et info2) dans les lignes d'un bloc :

    si info1 est vide et info2 non vide, alors, les test est VRAI
    si info1 est non vide et (info2 non vide ou vide) alors le test est FAUX
    le cas vide, vide n'existe pas..

    merci de votre aide

    cordialement

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Re,

    Je reste sur ma suggestion de document XML que tu n'est pas obligé de sauvegarder par la suite.

    à l'ouverture du fichier texte, tu ouvres/crées un nouveau document XML
    Voilà un shéma/pseudo 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
    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
    45
    46
    47
     private 
       XML : IXMLDOCUMENT;
     
     
      var  rootnode : IXMLNODE; 
            TitreNode : IXMLNode;
            LignesNode : IXMLNode;    
     
            function AddTitre(node : IXMLNode;titre : String) : IXMLNode;
            begin
               Result:=Node.AddChild('Titre');
               Result.Attributes['intitulé']:=Titre; 
            end;
            function AddSection(node : IXMLNode;titre : String) : IXMLNode;
            var SectionNode : IXMLNode;
            begin
                SectionNode:=Node.AddChild('Section');
                SectionNode.Attributes['nom']:=Titre; 
                SectionNode.Attributes['Visible']:='False';
                result:=SectionNode.AddChild('Lignes'); 
            end;
            function AddLigne(node : IXMLNode;valeur : String);
            var Anode : IXMLNode; 
            begin
               ANode:=Node.AddChild('Ligne');
               Anode.Text:=Valeur;
            end;
     
     
      begin
      XML := NewXMLDocument;
      XML.Encoding := 'utf-8';
      RootNode := XML.AddChild('XML');
      // je fais l'impasse sur une lecture classique de ligne d'un fichier texte  
      // à la lecture d'une ligne 
      si titre alors TitreNode:=AddTitre(RootNode,'letitre')
      si section alors 
        begin 
           // changer l'attribut visible en fonction du traitement des lignes de la section !
          if Assigned(SectionNode) then                                                                ! 
             begin                                                                                              !
              if moncritère then SectionNode.Attributes['Visible']:='Oui'                         ! Bloc à faire aussi si changement de titre ou fin de fichier
                                else SectionNode.Attributes['Visible']:='Non';                       !
              end;                                                                                              !
          SectionNode:=AddSection(TitreNode,'lasection');
       end;
      si ligne alors AddLigne(LignesNode,'le texte de la ligne');
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  10. #10
    Membre confirmé Avatar de cantador
    Homme Profil pro
    Chef de projet
    Inscrit en
    Mars 2006
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2006
    Messages : 569
    Points : 484
    Points
    484
    Par défaut @SergioMaster
    Bonjour,

    d'après l'heure de ton message tu as posté avant moi.
    je ne travaille quasiment pas avec XML..(à tord peut-être..)

    Je souhaiterai plutôt une autre solution ou une optimisation de celui que je propose
    bien que ta méthode soit élégante et permet de mettre un attribut à un bloc.
    à noter que je suis obligé de lire toutes les lignes d'un bloc avant de pouvoir mettre
    le test à VRAI ou FAUX..

    et enfin, je dois relire ensuite soit les blocs VRAI ou les blocs FAUX en récupérant quelques écritures qui y sont contenues.
    une fois cette ultime opération terminée, je vais devoir afficher les résultats de mon étude dans un Grid.

    Pour l'instant, le code que j'ai écrit à la hâte, me permet de stocker tous mes blocs en 100 ms.
    reste à la suite à coder, bien entendu..

    cordialement

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

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 496
    Points : 2 762
    Points
    2 762
    Billets dans le blog
    10
    Par défaut Une idée
    Avec un TMemo et un TTreeView

    Nom : i1.png
Affichages : 375
Taille : 8,0 Ko

    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      ms1 : TMemoryStream ;
    begin
      ms1 := TMemoryStream.Create ;
      TreeView1.SaveToStream(ms1);
      ms1.Position := 0 ;
      Memo1.Lines.LoadFromStream(ms1);
      ms1.Free ;
      Memo1.Lines.Text := StringReplace(Memo1.Lines.Text,#9,'#',[rfReplaceAll]) ;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      ms1 : TMemoryStream ;
      sl1 : TSTringList ;
    begin
      sl1 := TStringList.create ;
      sl1.Text := StringReplace(Memo1.Lines.Text,'#',#9,[rfReplaceAll]) ;
      ms1 := TMemoryStream.Create ;
      sl1.SaveToStream(ms1);
      ms1.Position := 0 ;
      TreeView1. LoadFromStream (ms1);
      ms1.Free ;
      sl1.free ;
      TreeView1.FullExpand;
    end;

  12. #12
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    étant donné que tu passes par un visuel
    une fois cette ultime opération terminée, je vais devoir afficher les résultats de mon étude dans un Grid.
    peut être pourrais-tu faire d'une pierre 2 coups en utilisant non pas une Grid classique mais une virtualstringGrid,
    il serait facile de gérer l'ouverture/visibilité d'une section (après tout c'est non seulement une grille mais aussi un Tree)
    tout ça avec un code "à la manière" dont j'ai rempli le XML

    ceci étant mon code n'est pas très bien fichu étant fait à la va-vite je n'ai pas très bien pris en compte ce que dans l'ancien temps on nommait les ruptures
    de contrôle (changement de type de ligne), programme "classique" de gestion de données

    [Edit]Damned ! grillé par Alweber quant à l'idée du treeview
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  13. #13
    Membre confirmé Avatar de cantador
    Homme Profil pro
    Chef de projet
    Inscrit en
    Mars 2006
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2006
    Messages : 569
    Points : 484
    Points
    484
    Par défaut structurer un fichier texte
    Bonjour,

    le Treeview, intéressant mais l'objectif n'est pas de reconstituer l'arborescence
    mais d'extraire des informations de ces relations et de les afficher de cette manière :

    Nom : image1.jpg
Affichages : 291
Taille : 11,6 Ko

    peut-être que j'aurai du mieux préciser les choses.
    merci à tous pour ces idées.

    c'est à moi de continuer

    @+

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

Discussions similaires

  1. [PHP 5.3] Structurer un fichier text
    Par vainuiz dans le forum Langage
    Réponses: 6
    Dernier message: 04/04/2012, 21h12
  2. structuration de fichier texte
    Par haifas dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 17/06/2011, 11h19
  3. [MySQL] créer un fichier texte selon une structure
    Par pascale86 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 10/12/2007, 14h44
  4. lecture fichier texte pointeur et structure
    Par shermav dans le forum C
    Réponses: 8
    Dernier message: 13/04/2007, 23h44
  5. Structure fichier texte..
    Par petitcoucou31 dans le forum Langage
    Réponses: 12
    Dernier message: 25/04/2006, 22h47

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