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

C++ Discussion :

lire fichier texte:pb getline


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 8
    Points
    8
    Par défaut lire fichier texte:pb getline
    Bonjour,

    j'ai un pb bizarre:
    J'ai un fichier texte avec 3 millions de lignes
    lorsque je fais mon getline(std::ifstream InputFileSpotsAndVariance, string bf)
    j'ai certains resultats dans bf où j'ai des caractères bizarres alors que dans mon fichier texte tout est ok
    exmple: dans mon fichier texte ";scenario" et dans mon output j'ai ",scen/E§"

    Quelqu'un a-t-il une idée? pb de mémoire?

    merci

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Sans autre indication, il sera sans doute difficile de te répondre...

    Cependant, je pencherais sans doute pour un problème d'encodage de ton fichier:

    N'essayerais tu pas d'ouvrir un fichier encodé en UTF (ou similaire) en le faisant passer pour une fichier encodé ASCII
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 8
    Points
    8
    Par défaut
    mon fichier texte contient les lignes suivantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ......
    ;scenario=49999;t=0.12;St=2542.45;Vt=0.104439;
    ;scenario=49999;t=0.14;St=2227.2;Vt=0.158645;
    .....;
    dans ma fontion
    je declare mon stream
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::ifstream InputFile(path,ios::in);
    ensuite je parse avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    token=strtok(bf_cstr,sp);
    puis je fais le getline pour passer à la ligne suivante

    Le fichier texte m'a été envoyé par qqun. Je ne sais pas du tout comment il a été encodé.

    Vois tu eventuellement une solution pour palier à ce pb?

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Bon, apparemment, ce n'est pas un problème de codage du fichier.

    De prime abord, je dirais que le problème vient de l'utilisation de strtok, car l'utilisation des fonctions propres aux C est rarement compatible avec les classes proposées par C++.

    Mais, plutôt que de partir à la pêche en essayant de deviner quel est le problème réel, pourrait-on te demander de nous donner le code complet de ta fonction de lecture
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 8
    Points
    8
    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
    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
     
    	char *token;
    	char str[256];
    	string bf,ct;
    double t;
    	double st;
    	double vt;
    	char* bf_cstr;
    	char *sp=";";
    …
     
    while (InputFileSpotsAndVariance.eof()!=true){
    	getline(InputFileSpotsAndVariance,bf);
    	bf_cstr=(char*)bf.c_str();
     
    	while (bf_cstr!=NULL){				
     
    		token=strtok(bf_cstr,sp);
    		ct=token;
    		//scenar								j=atoi((ct.substr(ct.find_first_of('=')+1,ct.length()-ct.find_first_of('='))).c_str());
    		//time
    		token=strtok (NULL,sp);				
    		ct=token;							t=atof((ct.substr(ct.find_first_of('=')+1,ct.length()-ct.find_first_of('='))).c_str());
    		//st
    		token=strtok (NULL,sp);
    		ct=token;
    		st=atof((ct.substr(ct.find_first_of('=')+1,ct.length()-ct.find_first_of('='))).c_str());
     
    //vt
    		token=strtok (NULL,sp);
    		ct=token;							vt=atof((ct.substr(ct.find_first_of('=')+1,ct.length()-ct.find_first_of('='))).c_str());
     
    A[0][j]=st;
    A[1][j]=vt;
    	getline(InputFileSpotsAndVariance,bf);
    	bf_cstr=(char*)bf.c_str();
    	}
     
     
    }

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Oui... C'est bien ce qu'il me semblait, il y a de la place pour le progrès (soit dis sans offance )

    Tu mélanges allègrement du C avec du C++, et, à moins de savoir exactement ce que tu fais, c'est en général une bien mauvaise idée.

    Pour commencer, je voudrais attirer ton attention sur le fait que les flux C++ disposent d'un opérateur de conversion implicite en booléen qui vaut true si la prochaine tentative de lecture est sensée réussir, et donc, entre autres choses, si la fin du fichier n'a pas été atteinte.

    Comme la fin de lecture est loin d'être la seule raison pour laquelle la lecture suivante risque d'échouer, il est fortement préférable de profiter de cet opérateur de conversion

    Il se fait que la fontion getline renvoie... le flux à partir duquel elle a travailler.

    Tu peux donc, afin de te faciliter la vie, effectuer une boucle de type "tant que" dont la condition pour y retrourner est que le flux soit valide, sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(std::getline(InputFileSpotsAndVariance,str))
    (Au fait, si j'avais été toi, j'aurais sans doute choisi un nom encore plus long pour le flux à utiliser, même si celui-ci est particulièrement parlant sur ce que tu lis )

    Ensuite, comme je te l'ai fait remarquer plus haut, l'utilisation des fonctions issues de C sont rarement la meilleure manière de travailler en C++, ne serait-ce que par leur manque récurrent de sécurité à l'utilisation.

    Or, il se fait que C++ propose une classe géniale pour transformer une chaine de caractères en "n'importe quoi d'autre" et réciproquement: la classe stringstream.

    (Nota: je pourrais aussi te parler de boost.tokenizer qui serait sans doute idéal pour tes besoins, mais je vais me contenter de donner une solution "a mano" )

    Cette classe permet de récupérer n'importe quoi (et surtout des types primitif) au départ d'une chaine de caractères en utilisant exactement la même syntaxe que pour les autres flux (les opérateurs << pour introduire une donnée dans le flux et >> pour récupérer une donnée à partir du flux), et comble de bonheur, elle est compatible avec la fonction libre getline, dont tu l'ignore peut-être, mais elle supporte un troisième paramètre qui représente le caractère de séparation

    Tu pourrais donc envisager de vérifier par la même occasion que ton fichier est "correctement formé"

    tu pourrais donc te "contenter" d'un code proche de
    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
    std::string str; // la chaine utilisée pour la lecture de la chaine
    while(std::getline(InputFileSpotsAndVariance,str)) // j'ai repris ton nom :D
    {
        /* création d'un flux de conversion */
        std::stringstream ss;
        /* on place la chaine lue dans le flux de conversion */
        ss<<str;
        /* il nous faut :
         * - une chaine de caractères
         * - un entier (pour représenter scenario)
         * - deux réels (pour représenter respectivement St et Vt)
         */
        std::string temp;
        int scenario;
        double st;
        double vt;
        std::getline(ss,temp,'='); // récupération de la première parite
        if(temp!=";scenario") // la première donnée doit avoir trait au scenario
            throw badFileFormat(); // à toi de créer cette classe d'exception ;)
        if(!ss>>scenario) // on lit la première donnée
                          // si la lecture échoue, le format du fichier n'est pas bon
            throw badFileFormat();
        std::getline(ss,temp,'='); //récupération de la deuxième partie
        if(temp!=";St") // la deuxième donnée doit avoir trait à St
            throw badFileFormat(); 
        if(!ss>>st) // on lit la deuxième donnée
                    // si la lecture échoue, le format du fichier n'est pas bon
        std::getline(ss,temp,'='); // récupération de la troisième partie
        if(temp!=";Vt") // la deuxième donnée doit avoir trait à Vt
            throw badFileFormat(); 
        if(!ss>>vt) // on lit la deuxième donnée
                    // si la lecture échoue, le format du fichier n'est pas bon
        /* le traitement que tu veux: je me contente ici de réafficher les
         * données récupérées :D
         */
        std::cout<<"scenario "<<scenario<<" valeur de St "<<st
                 <<"valeur de Vt "<<vt;
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 8
    Points
    8
    Par défaut
    merci pour cette réponse complète et détaillée.
    Je te reviens asap pour te dire ce qu'il en est.

Discussions similaires

  1. java : lire fichier texte application web (war)
    Par drob38 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 07/07/2009, 23h31
  2. [VB.NET 2.0] lire fichier text
    Par Emcy dans le forum Windows Forms
    Réponses: 4
    Dernier message: 20/12/2006, 08h45
  3. Lire fichier texte
    Par kinouseb dans le forum VC++ .NET
    Réponses: 2
    Dernier message: 08/11/2006, 17h01
  4. Lire fichier texte en respectant la police, la forme
    Par loupin dans le forum Langage
    Réponses: 2
    Dernier message: 10/07/2006, 22h49
  5. Lire fichier Texte
    Par rprom1 dans le forum Entrée/Sortie
    Réponses: 12
    Dernier message: 15/03/2006, 16h36

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