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 :

ifstream et getline


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 116
    Points : 62
    Points
    62
    Par défaut ifstream et getline
    Bonjour,

    J'ai un soucis pour récuperer les lignes d'un fichier que je charge :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    std::ifstream stlfile_stream( "monfichier" );
    if(!stlfile_stream ) 
    	return 1;
    // chargement du fichier "monfichier" qui contient deux lignes.
     
    int nblines = std::count(std::istreambuf_iterator<char>( stlfile_stream ), std::istreambuf_iterator<char>(), '\n' );
    // nblines=2 => ok
    for( std::string line; std::getline( stlfile_stream, line ); ){ line; }
    //line="" => ko
    En parcourant la doc et google, je ne trouve pas de syntaxe qui diffère de la mienne alors je ne vois pas trop d'où celà peut venir.

    J'ai aussi tenté de passer par un stringstream avec rdbuf() mais sans succès.

    Si quelqu'un pouvait m'éclairer.

    Merci par avance.

  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,

    Tu ne dois pas te baser sur la valeur de la chaine après la lecture, mais bel et bien sur l'état de ton flux après celle-ci.

    Tu ne peux en effet pas présumer de ce que vaudra ta chaine si la lecture échoue: aura-t-elle gardé sa dernière valeur "valide", sera-t-elle vide sera-t-elle éventuellement composée des bits du cluster qui suivent la fin de fichier

    Personne ne peut le dire avec certitude, car cela dépend grandement de ton compilateur.

    Par contre, une chose est sure, c'est que getline renvoie... le flux que tu essaye de lire.

    Et, comme il existe un opérateur de conversion en booléen en fonction de l'état du flux (la lecture suivante réussira ou non), il est beaucoup plus facile de placer une condition sur ce que renvoie getline.

    Tu ne dois donc même pas t'amuser à essayer de compter les lignes d'une manière ou d'une autre avant de les utiliser, étant donné que cela t'oblige à... parcourir deux fois le contenu de celui-ci: une fois pour déterminer le nombre de lignes, une fois pour... les gérer.

    Au final, la meilleure des solution est donc d'utiliser une boucle "tant que" avec comme condition de sortie le fait que le flux refusera la lecture suivante:
    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
    int main()
    {
        int cpt= 0; // pour compter les lignes
        std::string str; // pour récupérer la ligne lue
        std::ifstream ifs("fichier.txt"); // le flux de fichier
        while(std::getline(ifs,str)) // on ne rentre dans la boucle que si la
                                     //  lecture a réussi
        {
            /* on incrémente le compteur, pour que la premiere ligne soit la
             * numéro 1
             */
            ++cpt;
            /* le traitement à appliquer à la ligne */
            std::cout<<"line "<<cpt<< " "<<str<<std::endl;
     
        }
        std::cout<<"fini, avec "<<cpt<<" lignes lues"<<std::endl;
        return 0;
    }
    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
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 116
    Points : 62
    Points
    62
    Par défaut
    Ok ! Merci beaucoup pour tes explications .

    J'ai une dernière question à ce sujet.

    En fait j'enregistre des triangulations dans mon fichier, et je suis parti sur la base :" 1 triangulation pour 1 ligne" (en gros j'ajoute mes coordonnées bout à bout séparées par des '\t').
    Ce n'est surement pas la meilleure solution, mais c'était la plus simple.

    Est ce qu'avec getline(..) je risque de perdre des données si ma ligne est trop longue ? Si oui, comment puis-je prévenir cette erreur ?

  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
    Il n'y a strictement aucun risque: bien qu'il semble, selon ton éditeur de texte, prendre de nombreux espaces (souvent entre 4 et 8, parfois plus), \t ne représente en réalité... qu'un seul caractère.

    Comme getline s'arrête au premier séparateur rencontré ( '\n' par défaut, mais tu peux en préciser d'autres si le besoin s'en fait sentir) et que les chaines de caractères sont limitées à... l'espace maximal dont tu dispose en mémoire (ou peu s'en faut), tu comprendra que, sous la forme que je te présente, le risque est, si pas nul, très proche de l'être, et que, si cela devait arriver quand même, ce serait essentiellement du à une limitation au niveau de ton système, et qu'il n'y aurait donc pas grand chose à faire pour y palier
    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
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 116
    Points : 62
    Points
    62
    Par défaut
    Nickel Merci.

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

Discussions similaires

  1. Re getline / ifstream
    Par le_fif dans le forum SL & STL
    Réponses: 5
    Dernier message: 06/10/2009, 10h17
  2. erreur ifstream / getline
    Par le_fif dans le forum C++
    Réponses: 3
    Dernier message: 05/10/2009, 11h57
  3. extraction d'un gros fichier ifstream::getline
    Par Invité4 dans le forum SL & STL
    Réponses: 5
    Dernier message: 22/01/2009, 15h13
  4. Problème getline(ifstream, string)
    Par OliverSleep dans le forum C++Builder
    Réponses: 2
    Dernier message: 24/05/2007, 17h09
  5. Probleme avec ifstream
    Par maitre hibou dans le forum SL & STL
    Réponses: 12
    Dernier message: 12/05/2004, 13h33

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