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 :

Lecture fichier texte ligne par ligne


Sujet :

C++

  1. #1
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut Lecture fichier texte ligne par ligne
    Bonjour,
    Je cherche à lire un fichier texte ligne par ligne pour récupérer les valeurs contenues dans ce fichier et effectuer des calculs avec.
    Le problème n'est pas la lecture du fichier en soi mais la difficulté de gérer les cas où le fichier n'aurait pas le format attendu (typiquement nombres de valeurs par ligne différent ou caractères parasites dans le fichier).

    Si on a un fichier de cette forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    3.14        0        1.51        2.28
    1        0.3        2.25        1.14
    3.2        5.5        6.2        0.1
    4.1        0        2.3        3.2
    Pas de problème, on a le bon nombre de valeurs par ligne.


    Par contre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3.14        0        1.51          // manque une valeur à cette ligne
    1        0.3        2.25        1.14
    Ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3.14        0        1.51        2.28
    1        0.3        2.25        1.14        3.2        5.5        // deux valeurs en trop sur cette ligne
    Ou plus vicieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    3.14        0        1.51        2.28
    1        0.3        2.25        1.14
    3.2        5.5        6.2        0.1
    4.1        0        2.3        3.2 // j'ai ajouté un espace à la fin de cette ligne
    Je lis le fichier de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while(!(m_file.getStream().eof()))
    {
      // je lis une ligne du fichier et récupère les valeurs
      initializeParameters();
      // test des valeur lues
      if(hasValideParameters())
      {
        // j'effectue mes calculs avec ces valeurs
      }
    }
    Ce code marche si j'ai le bon nombre de valeurs par ligne et si la dernière ligne ne se finit pas par un espace (sinon un tour de boucle supplémentaire avec des valeurs aléatoires).
    Je souhaiterais donc vérifier de manière simple que le fichier d'entrée soit bien "formaté".

    Je ne sais pas si c'est suffisemment clair.

    Merci de votre aide.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    je pense qu'il faudrait plutôt modifier les fonctions que tu présentes pour gérer ces "cas".
    A priori avec une utilisation correcte des flux et opérateurs >> le mauvais formatage décrit n'est pas problématique.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    jmv
    jmv est déconnecté
    Membre confirmé Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Points : 603
    Points
    603
    Par défaut
    Bonjour,

    Personnellement, lorsque j'ai un fichier à lire ligne par ligne, j'utilise la fonction std::getline().

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ifstream fichier("...");
    string ligne;
    while (getline(fichier,ligne)) {
        traitement de la ligne ici
    }

  4. #4
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    OK, je vois ce que tu veux dire, j'ai besoin de rediriger les valeurs de la manière 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
      std::fstream m_file;
      std::string sFileIn;
      std::string strCurrentLine;
      bool bFileIn = false;
     
      int param1;
      double param2;
      double param3;
      double param4;
     
      do
      {
    	  std::cout <<"\n    Name of the entry file : ";
    	  std::getline(std::cin, sFileIn);
    	  m_file.open(sFileIn.c_str(),std::ios::in);
     
    	  if(!m_file.is_open())
    	  {
    		  std::cout <<"\t\t ---> File  "<<sFileIn<<" doesn't exist !";
    	  }
    	  else
    	  {
    		  bFileIn = true;
    	  }
      }while(bFileIn == false);
     
      while(std::getline(m_file, strCurrentLine))
      {
        std::stringstream stream(strCurrentLine);
     
        stream>>param1;
        stream>>param2;
        stream>>param3;
        stream>>param4;
       /* ... */
     
      }
      std::cout <<"\n  Close file."<<"\n\n";
      m_file.close();
    Est-ce une bonne solution?

  5. #5
    jmv
    jmv est déconnecté
    Membre confirmé Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Points : 603
    Points
    603
    Par défaut
    Citation Envoyé par LinuxUser Voir le message
    Est-ce une bonne solution?
    Je pense que oui, fait l'essai, mais remplace std::stringstream par std::istringstream (ligne 29).

    [EDIT]
    Et std::fstream par std::ifstream à la ligne 1.
    Dans la mesure du possible, évite les flux bidirectionnels si tu n'en a pas besoin.
    [/EDIT]

  6. #6
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    OK, j'ai corrigé, ça à l'air de marcher impec.
    Par contre, faut eviter les flux bidirectionnelles si on en a pas besoin, uniquement pour une raison de clareté (pour indiquer qu'on lu ou écrit seulement) ou y a t ils d'autres raisons plus pragmatiques (optimisation, mémoire, temps execution, ...)?

  7. #7
    jmv
    jmv est déconnecté
    Membre confirmé Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Points : 603
    Points
    603
    Par défaut
    Citation Envoyé par LinuxUser Voir le message
    Par contre, faut eviter les flux bidirectionnelles si on en a pas besoin, uniquement pour une raison de clareté (pour indiquer qu'on lu ou écrit seulement) ou y a t ils d'autres raisons plus pragmatiques (optimisation, mémoire, temps execution, ...)?
    Raison de clareté, oui sûrement.
    Mais il peut aussi y avoir un problème de droit d'accès, si tu n'as que les droits de lecture sur un fichier, tu ne pourras pas l'ouvrir avec std::stream.
    J'ai rencontré des problèmes avec une liaison série sous linux, ça ne marchait pas avec un flux bidirectionnel mais ça marchait bien avec un flux et entré et un autre en sortie. Je n'ai jamais compris pourquoi mais depuis je me méfie.

  8. #8
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    OK, c'est bon à savoir.

    Merci beaucoup pour votre aide, problème résolu.

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

Discussions similaires

  1. Réponses: 13
    Dernier message: 27/07/2012, 18h38
  2. lecture ligne par ligne d'un fichier texte
    Par toutounesan dans le forum VB.NET
    Réponses: 4
    Dernier message: 16/06/2011, 18h28
  3. Réponses: 2
    Dernier message: 26/04/2011, 19h23
  4. Réponses: 3
    Dernier message: 28/11/2010, 19h56
  5. Réponses: 20
    Dernier message: 09/02/2006, 09h45

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