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 :

TextFile et EOF


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 36
    Par défaut TextFile et EOF
    Hello tous le monde.

    Je suis en train de réaliser un petit utilitaire qui doit récupérer une info sur chaque ligne de plusieurs fichiers textes. Jusque la, aucun problème. Chaque fichier est ouvert dans une TStringList que je parcours ensuite.
    La ou ca se corse, c'est que certains fichiers ne se chargent pas complètement . J'ai exagalement essayé de le chargé dans un TextFile, et de le parcourir par ReadLn, mais idem.

    Si je sauvgarde ma StringList dans un fichier texte, il ne fait pas la même taille que le fichier d'origine.
    J'ai donc chargé le fichier dans un TFileStream, pui je l'ai parcouru octet par octet. J'ai remarqué que lorsque j'arrivait à l'endroit ou je constate mon problème, je tombe sur le caractère #0. Il me semble bien que ce caractère signifie qu'on arrive à la fin du fichier, d'ou mon problème. Lorsque je l'ouvre dans le bloc note, il charge bien tout le fichier et j'ai un espace (ou tout du moins ce qui y ressemble) à la place du #0.
    J'ai contourné le problème en lisant caractère par caractère dans un stream, et en remplacant les #0 par des espaces, mais c'est pas très rapide.

    Auriez vous une solution pour contourner ce problème ?

    Merci d'avance
    Birdyz

  2. #2
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 69
    Par défaut
    il faut que tu surchages la methode TStrings.SetTextStr comme ceci :
    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
     
    procedure TMaStringList.SetTextStr(const Value: string);
    var
      P, Start: PChar;
      S: string;
    begin
      BeginUpdate;
      try
        Clear;
        P := Pointer(Value);
        if P <> nil then
          while (P - Pointer(Value)) < Length(Value) do
          begin
            Start := P;
            while not (P^ in [#10, #13]) do Inc(P);
            SetString(S, Start, P - Start);
            Add(S);
            if P^ = #13 then Inc(P);
            if P^ = #10 then Inc(P);
          end;
      finally
        EndUpdate;
      end;
    end;
    et ca devrait marcher avec un TMaStringList dérivant de TStringList

    Bruno

  3. #3
    Membre Expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 573
    Par défaut
    Salut

    Le caractère #0 ne signifie pas fin de fichier mais fin de chaîne de caractère (au sens du langage C), Delphi est compatible avec ce modèle de chaîne de caractères pour mieux communiquer avec les API.

    Ceci dit une chaîne longue Delphi peut comporter un zéro n'importe où sans provoquer la diminution de la chaîne, la taille (length) tient compte du nombre exact de caractères. Mais lorsque tu affecte la chaîne à une propriété d'un composant visuel (TLabel, TMemo...), le contenu est tronqué au premier #0 rencontré.

    Si ton fichier comporte des #0, ce n'est pas un pur fichier texte. Il convient donc de t'interroger sur le rôle de ce caractère dans le fichier (séparateur de ligne...), ensuite tu dois déterminer comment le traiter (le transformer en #10 par exemple).

    Pour lire ton fichier, il est effectivement préférable de passer par un flux (TFileSTream) en lisant un bloc de caractère (de 4 ko par exemple) dans un tableau de caractères, tu analyse le contenu de ce tableau puis tu le convertis en string. Mais surtout ne lis pas caractère par caractère car il évident que cela va ramer puisque tu augmentes le nombre de lecture physique du fichier.

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 36
    Par défaut
    Merci Bruno@Chrysis. Ca marche presque
    Je m'explique : toutes les lignes de mon fichier sont désormais chargé dans ma StringList, mais les lignes contenant le #0 sont tronquées une fois arrivé sur ce caractère. J'ai essayé de faire des modificartion, mais j'ai encore un peu de mal avec les pointeurs, et j'arrive pas à modifier la procédure.
    J'ai ajouter #0 pour avoir [#10, #13, #0], et ajouter la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if P^ = #0 then Inc(P);
    Ca me charge bien les caractères, mais ca me remplace le #0 par un saut de ligne.

    Birdyz

  5. #5
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 69
    Par défaut
    Je ne comprends pas trop ce que tu entends par sont tronquées ? Le type string en delphi peu contenir le caractere #0... je viens de faire un essai et j'obtiens bien une ligne de mon StringList avec un #0 dedans sans que cette ligne ne soit tromquée

    Bruno

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 36
    Par défaut
    Et bien en fait, une ligne faisant 200 caractères dans mon fichier d'origine, n'en fait plus que 99 dans la StringList si le 100ème caractères est un #0.

    @e-ric : je pense que je vais être obligé de faire comme ca. En fait, ce qui est bizarre (mais qui n'a rien a voir avec Delphi), c'est que le logiciel produisant ces fichiers ne le fait que sur un faible pourcentage. J'avais fait de la lecture octet par octet afin de voir ce qui posait problème.

  7. #7
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 69
    Par défaut
    Si tu fais bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while not (P^ in [#10, #13]) do Inc(P);
    alors cela ne tronque pas mais effectivement si tu ajoutes #0 alors la boucle s'arrete et tu as bien une tronquature sur le #0

    Bruno.

    PS: qu'est-ce que tu voulais dire par "j'arrive pas à modifier la procédure" ?

  8. #8
    Membre Expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 573
    Par défaut
    Citation Envoyé par bruno@chrysis
    Je ne comprends pas trop ce que tu entends par sont tronquées ? Le type string en delphi peu contenir le caractere #0... je viens de faire un essai et j'obtiens bien une ligne de mon StringList avec un #0 dedans sans que cette ligne ne soit tromquée
    Cela ne contredit absolument pas ce que j'ai dit, une chaîne peut contenir un ou même plusieurs #0. Une StringList est une liste de chaîne donc pas de problème, chaque chaîne peut contenir des #0. Par contre affecter une telle stringList à un TMemo via la propriété Lines va sans doute produire des surprises.

    Si j'ai compris, le fichier de données contient des lignes de 200 caractères terminées par des #0 si la taille est inférieure à 200.

    Si les données sont placées dans un PChar pointant surt un tableau de 200 caractères, il suffit d'employer StrPas pour convertir le tableau en String Delphi.

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  9. #9
    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
    A mon avis l'effet de "troncage" de son fichier vient du fait qu'il y a des caractères ASCII < 32 dans son fichier et qu'il y a surement des #8 (delete) ou autres caractères bien sympatique du genre ^^

    Le passage par la lecture via un TFileStream est nécessaire dans ce cas la.
    Modérateur Delphi

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

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

Discussions similaires

  1. equivalent EOF
    Par $grm$ dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 21/05/2004, 16h48
  2. Problème avec Do while rs.EOF
    Par lauraned dans le forum ASP
    Réponses: 12
    Dernier message: 21/05/2004, 12h00
  3. Fonction If avec rs.eof problème
    Par M1000 dans le forum ASP
    Réponses: 5
    Dernier message: 24/03/2004, 17h10
  4. modification de fichier EOF
    Par scorbo dans le forum C
    Réponses: 9
    Dernier message: 28/11/2003, 11h35
  5. RecordSet en EOF
    Par jfphan dans le forum ASP
    Réponses: 3
    Dernier message: 06/11/2003, 16h47

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