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 un fichier de données ligne par ligne et récupérer les valeurs dans des variables


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Septembre 2006
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 21
    Points : 15
    Points
    15
    Par défaut Lire un fichier de données ligne par ligne et récupérer les valeurs dans des variables
    Bonjour a tous,
    Je suis débutante en C++ et je trouve des problèmes pour manipuler un fichier de données.
    J'ai un fichier qui contient des données de la forme :
      2    3
      10   10   10
    
       0   3 2 3 7 
       2   2 6 4 
    Ces différentes valeurs doivent être classés dans des variables différentes. Par exemple à partir de la ligne 3 jusqu'à la fin (pour des fichiers de tailles plus grande également) je dois lire ces lignes une a une et stocker la première valeur de chaque ligne dans un tableau Dactiv[i] et pour le reste je dois les classer dans une matrice que je déclare en tant que vector <vector <int> > (notons que le tableau possède n lignes mais le nombre de colonnes pour chaque ligne est différent). Est ce que c'est possible de le faire en C++?

    J'ai fait un bout de code en C++ mais qui me donne des valeurs erronées stockées dans les variables, le code est le suivant:
    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
        int n; 
        vector <int> NBsucc; 
        vector <int> succ; 
        vector <vector <int> > Successeurs; 
        int R; 
        vector <int> ri;
        vector <int> Dactiv; //vecteur qui contient la première case de chaque ligne a partir de la ligne 3
     
        filebuf fichier; 
        filebuf *ouvert=fichier.open("Pat5.rcp", ios_base::in); 
        if(!ouvert)
        {
            cout<<"Probleme d'ouverture du fichier "<< endl;
            exit(1);
        }
        istream inFile(&fichier); 
     
        //Lire 1er element de la 1ere ligne du fichier 
        inFile >> n; 
        Dactiv.resize(n);
        NBsucc.resize(n);
     
        //Lire 2eme element de la 1ere ligne du fichier (nombre de ressources)
        inFile >> R; 
        ri.resize(R);
     
        // 2eme ligne
        for(int j = 0; j < R; j++)
            inFile >> ri[j]; 
     
        /* Dans une boucle for de la 3eme ligne jusqu’à la fin */ 
        for(int k=0; k < n; k++)
         {
            // 1ere case de chaque ligne dans le tableau Dactiv
            inFile >> Dactiv[k]; 
            //2eme case de chaque ligne dans un tableau NBsucc
            inFile >> NBsucc[k];
            //allocation memoire pour la matrice Successeurs
            Successeurs.resize(n);
            for(int i = 1; i < NBsucc[k]; i++)
                Successeurs[i].resize(NBsucc[k],false);
     
            //de 3eme case a la fin 
            for(int j = 0; j < NBsucc[k]; j++)
                inFile >> Successeurs[k][j] ; // les successeurs j de tous les nœuds k
        }
    Les valeurs des tableaux Dactiv doivent être 0 et 2 celles de NBsucc doivent être 3 et 2. Mais le résultat n'affiche pas les bonnes valeurs?
    C'est quoi le problème?
    Merci

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Je t'invite à lire notre faq sur la lecture de fichier.

    Notamment, la lecture ligne à ligne

    Ca devrait t'aider.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre à l'essai
    Inscrit en
    Septembre 2006
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par leternel Voir le message
    Je t'invite à lire notre faq sur la lecture de fichier.

    Notamment, la lecture ligne à ligne

    Ca devrait t'aider.
    Bonjour,
    Je vous remercie pour votre réponse. J'ai consulté cette rubrique mais cette dernière permet de lire le fichier ligne par ligne et de lire la ligne complète et la stocker dans une variable string. Moi par contre je veux accéder au fichier ligne par ligne et dans chaque ligne accéder aux différentes valeurs dans une même ligne pour les stocker dans un fichier texte.
    Est ce que je peux utiliser la même technique et après accéder aux variables?
    Merci pour votre réponse.
    Cordialement,
    Nadia

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Ce que je fais en général est proche du code suivant:

    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
    //méthode privée.
    void data::append(istream& input) {
    	std::string line;
    	std::istringstream iss;
     
    	while( std::getline(input, line) ) {
    		if(/*line empty*/) continue;
    		//retirer les commentaires.
    			//utiliser string::find() pour chercher un '#'
    			//remplacer line par line.substr(0, position du #)
     
    		//éventuellement sauter les lignes blanches
     
    		//accepter la partie restante de la ligne
    		iss.str(line);
    		//lire la donnée
    		int x, y;
    		iss >> x >> y;
    		//utiliser la donnée, par exemple:
    		this.add(point(x,y));
    	}
    }
    Cela dit, je viens de le réécrire sans relire la référence. Il faut peut-être un c_str() pour remplir le istringstream.

    Dans le cas d'un vecteur d'entier, ca pourrait donner ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //...
    		//lire la donnée
    		vector<int> vect;
                    int i;
    		while(iss>> i) vect.push_back(i);
    //...
    A l'usage, ca pourrait donner un constructeur tel que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    data::data(const char* filename) {
    	std::ifstream file(filename);
    	if(!file) throw file_not_found_exception(filename); //en supposant que tu aies une telle classe;
    	append(file);
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Membre à l'essai
    Inscrit en
    Septembre 2006
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 21
    Points : 15
    Points
    15
    Par défaut getline pour accéder aux lignes d'un fichier
    Bonjour,
    Mon code est le suivant :

    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
    	filebuf fichier; //filebuf Stream buffer to read from and write to files
    	filebuf *ouvert=fichier.open("Pat1.rcp", ios_base::in); //ios_base::in (for input) File open for reading, supporting input operations
     
    		if(!ouvert)
    			{
    			        cout<<"Probleme d'ouverture du fichier "<< endl;
    				exit(1);
    			}
     
    		istream inFile(&fichier);
     
                    std::string ligne; // variable contenant chaque ligne lue 
     
    	      while ( std::getline( fichier, ligne ) ) 
    	      { 
     
    		//Lire 1er element de la 1ere ligne du fichier (nombre de nœuds)
    		inFile >> n; 
     
    	      }
    L’exécution généré l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(int, char**)’:
    ../c++/test2.cpp:77:43: error: no matching function for call to ‘getline(std::filebuf&, std::string&)’
    ../c++/test2.cpp:77:43: note: candidates are:
    /usr/include/c++/4.6/bits/basic_string.tcc:1070:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::getline(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&, _CharT)
    /usr/include/c++/4.6/bits/basic_string.h:2734:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::getline(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&)

    Est ce que quelqu'un pourrait m'expliquer l'erreur est due à quoi?
    Merci
    nadia

  6. #6
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Bonjour,

    Utilise ifstream plutôt que istream et filebuf. D'ailleurs getline attend un istream, et tu passes un filebuf.

  7. #7
    Membre à l'essai
    Inscrit en
    Septembre 2006
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par the Hound Voir le message
    Bonjour,

    Utilise ifstream plutôt que istream et filebuf. D'ailleurs getline attend un istream, et tu passes un filebuf.
    Merci pour votre réponse. J'ai pensé a faire ça aussi mais le problème c'est que en utilisant ifstream je ne peux pas utiliser inFile pour récupérer mes données

    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
    std::ifstream fichier( "Pat1.rcp" ); 
     
    	ifstream inFile(&fichier);
    	    std::string ligne; // variable contenant chaque ligne lue 
     
    	    // cette boucle s'arrête dès qu'une erreur de lecture survient 
    	    while ( std::getline( fichier, ligne ) ) 
    	      { 	
    		// afficher la ligne à l'écran 
    		std::cout << ligne << std::endl;
    		//Lire 1er element de la 1ere ligne du fichier (nombre de noeuds)
    		inFile >> n; //number of nodes on the graph
    		//b1.resize(n);
    		//b2.resize(n);
    		Dactiv.resize(n);
    		NBsucc.resize(n);
    	      }
    Ça donne ça comme erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     no matching function for call to ‘std::basic_ifstream<char>::basic_ifstream(std::ifstream*)’
    ../c++/test2.cpp:78:35: note: candidates are:
    /usr/include/c++/4.6/fstream:460:7: note: std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const char*, std::ios_base::openmode) [with _CharT = char, _Traits = std::char_traits<char>, std::ios_base::openmode = std::_Ios_Openmode]
    /usr/include/c++/4.6/fstream:460:7: note:   no known conversion for argument 1 from ‘std::ifstream* {aka std::basic_ifstream<char>*}’ to ‘const char*’
    /usr/include/c++/4.6/fstream:446:7: note: std::basic_ifstream<_CharT, _Traits>::basic_ifstream() [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.6/fstream:446:7: note:   candidate expects 0 arguments, 1 provided
    /usr/include/c++/4.6/fstream:420:11: note: std::basic_ifstream<char>::basic_ifstream(const std::basic_ifstream<char>&)
    /usr/include/c++/4.6/fstream:420:11: note:   no known conversion for argument 1 from ‘std::ifstream* {aka std::basic_ifstream<char>*}’ to ‘const std::basic_ifstream<char>&’

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    mais...
    premièrement, utilise la balise code (#)

    deuxièmement:
    Pourquoi créer un ifstream pour le mettre dans un autre?
    Ca n'a aucun sens.

    Et puis, quitte à continuer sur ton parser, reste dans ton autre discussion
    Note modération : messages déplacés
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  9. #9
    Membre à l'essai
    Inscrit en
    Septembre 2006
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Je suis désolée c'est la première fois que j'utilise le forum je savais pas comment le faire!
    Merci pour vos réponses. J'ai résolu ce problème
    Mais il reste encore un petit soucis, en fait je voulais savoir si en déclarant une matrice de la sorte vector < vector <int> > Mat et après faire des resize pour la taille allouée, est ce que c'est possible d'avoir une matrice qui n'est pas de taille régulière?
    Je m'explique: la matrice possèdera n lignes et mj colonnes (pour chaque ligne le nombre d’éléments n'est pas le même. La première ligne contient 2 éléments et la deuxième contient 3 etc.

    Code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Mat.resize(n);
    for(int i=0; i<n; i++)
    Mat[i].resize(L[j], false); //L vecteur initialisé
    Ça me génère pas d'erreur pour générer le code mais quand je lance le .exe ça donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Segmentation fault (core dumped)
    Je vous remercie pour votre réponse.

  10. #10
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Si c'est une vrai matrice, c'est anormale qu'elle ne soit pas au minimum rectangulaire.

    Si au contraire c'est un ensemble de série de valeurs, je te recommande l'usage d'une classe représentant chaque série.
    Surtout si les valeurs ont une nature pas tout à fait identique.
    Cette classe pourrait tout à fait contenir un vector.

    Dans la faq, il y a une paire de question sur les matrices et l'opérateur d'accès.
    Je te recommande d'aller y faire un tour, c'est instructif.
    comment et pourquoi utiliser operator() plutot que [][]

    Ta segmentation fault est simplement un accès à de la mémoire qui ne t'appartient pas.
    C'est soit un [] soit un * mal visé.
    Ca peut aussi être un delete malvenu.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

Discussions similaires

  1. lire un fichier texte ligne par ligne et récupérer des données
    Par nekcorp dans le forum Général Python
    Réponses: 8
    Dernier message: 13/04/2014, 22h33
  2. Réponses: 6
    Dernier message: 24/11/2008, 20h51
  3. Réponses: 2
    Dernier message: 22/06/2008, 15h41
  4. lire un fichier ligne par ligne
    Par peuf23 dans le forum C
    Réponses: 6
    Dernier message: 21/09/2005, 10h43

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