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 et classement des données


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut lecture fichier et classement des données
    Bonjour tous,

    J'ai un petit programme à faire pour jeudi mais je rencontre de grosses difficultés car je n'ai pas l'habitude du C++ et de la manipulation des chaines de caractères, c'est pour cela que je vous sollicite.

    Je dois faire un debut de programme où le main.cpp nous renvoi à une fonction input qui permettra de lire un fichier texte (de taille variable) et classer les objets dans des vecteurs (<vector>):

    Voici mon fichier texte (exemple):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # matrix name lattice_parameter atomic_volume
    matrix ferrite 2.85 1e-30
    matrix aluminium 1.85 1.2e-30
     
    #precipitate name lattice_parameter atomic_volume 
    precipitate VC 4.1
    precipitate Mg2Si 4
    precipitate Mg5Si6 4.7
     
    #element name stoechiometrique coeff
    Mg2Si 2 1
    Voici mon main.cpp (je ne sais pas trop comment allouer la memoire dynamique et en meme temps renvoyer le contenu du fichier txt à une fonction):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include "input.h"
    using namespace std;
    int *dataBase = NULL;
    int main(int argc, char **argv)
    {
        *dataBase = new string("dataBase.txt");
        input(&dataBase);
        delete dataBase;
        return 0;
    }
    Voici mon input.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifndef INPUT_H
    #define INPUT_H
    #include <string>
    void input(std::string *dataBase);
    #endif
    Voici mon input.cpp :
    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
    47
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include "input.h"
    using namespace std;
    vector <string> matrix;
    void input(string *dataBase)
    {
        string command,dump;
        *dataBase.open(*dataBase.c_str(),ios::in);
        while (!dataBase.eof())
        {
        *dataBase >> command;
            if(!dataBase.eof())
            {
                if(command=="#")
                {
                    getline(dataBase,dump); cout << dump << endl;
                }
                if(command=="matrix");
                {
                      string MatrixName;
                      double LatticeParameter, AtomicVolume;
                      cout << "Matrix command invoqued"  << endl;
                      command >> MatrixName;
                      command >> LatticeParameter;
                      command >> AtomicVolume;
                      *matrix = new Matrix(MatrixName, LatticeParameter, AtomicVolume);
                      matrix.push_back(_matrix);
                      cout << MatrixName << endl;
                      cout << matrix.size() << endl;
                }
                if(command=="precipitate");
                {
                       //ici je veux mettre le nom et nombre dans un vecteur
                       //mais ca sera comme au dessus pour matrix
                }
                if(command=="element");
                {
                        //ici je veux mettre le nom et nombre dans un vecteur
                       //mais ca sera comme au dessus pour matrix
                }
            }
    }
        dataBase.close();
    }
    mais franchement je suis perdu

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    j'ai apporté quelques modif à mon premier message car je me suis rendu compte qu'il y avait des erreurs (mais il en reste encore pas mal je pense )

    ==> En fait mon probleme est double:

    1°) j'ai l'impression que pour faire ce que je veux il n'y a pas besoin de faire plus de chose qu'une fonction (sous matlab j'ai deja fait des choses dans ce genre tres facilement) mais lorsque je passe à la pratique j'ai l'impression qu'il faudrait faire appel à des constructeurs/destructeurs....
    ==> pour resumer: je ne suis pas certains que programmer comme ceci soit la meilleurs solution

    2°) Mon second probleme est que j'ai des difficultés à mélanger toutes ces nouvelles notions: STRING, VECTOR, LECTURE DE FICHIER et à cela les pointeurs

  3. #3
    Membre expérimenté
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 227
    Par défaut
    Plusieurs questions :
    • Pourquoi la variable dataBase est-elle globale ?

    • Pourquoi passes tu l'adresse d'un pointeur à une fonction qui demande un pointeur ?

    • As tu remarqué que tu déclare un pointeur sur un entier (dataBase et que tu veut y stoocker un string ?


    • A ma connaissance la classe string ne possède pas de méthode open

    • Tu as réussi à compiler ton code

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    merci beaucoup d'avoir pris le temps de répondre,
    je ne suis pas arrivé à compiler, je vous ai présenté ici le programme presque complet que je voudrais pour vous donner une idée mais en fait j'ai essayer des choses plus simples et je ne suis pas arrivé non plus à compiler.

    Citation Envoyé par andnicam Voir le message
    Pourquoi la variable dataBase est-elle globale ?[/LIST]

    c'est surement une erreur de ma part
    : en fait dans les tuto que j'ai vu on fait comme cela pour allouer de la memoire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main()
    {
        int *variable = NULL;
        variable = new int; // Allocation de mémoire
        delete variable; // Libération de mémoire
        return 0;
    }
    Donc j'ai mis database dans le main pour prendre la meme structure que ci dessus

    Citation Envoyé par andnicam Voir le message
    Pourquoi passe tu l'adresse d'un pointeur à une fonction qui demande un pointeur ?
    c'est une erreur de ma part, j'ai confondu voila ce qui est correct à mon avis:
    Citation Envoyé par andnicam Voir le message
    As tu remarqué que tu déclare un pointeur sur un entier (dataBase et que tu veut y stoocker un string ?
    exact c'est encore une erreur , en fait dans les tuto que j'ai fait les pointeurs etaient toujours des int ou double donc j'ai fais ceci sans me rendre compte, ceci est plus correct je pense ?:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    string *dataBase = NULL;
    Citation Envoyé par andnicam Voir le message
    Pourquoi déclares tu cette variable de manière globale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector <string> matrix;
    Pour ce point je ne sais pas quoi repondre car je ne sais pas trop comment je dois structurer mon programme et je n'ai pas l'habitude d'utiliser vector, j'ai fais un peut par defaut en essayant de recopier des morceaux de code d'un tuto/faq
    (attention j'ai apporté une modif sur ce point par rapport à mon premier post)

    Citation Envoyé par andnicam Voir le message
    A ma connaissance la classe string ne possède pas de méthode open
    ah bon? comment faire donc pour lire mon fichier au travers de cette fonction input?

  5. #5
    Membre expérimenté
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 227
    Par défaut
    Pour ouvrir un fichier il faut utiliser les classes istream ou ifstream (Ouverture fichier).
    Je te conseille de jeter un oeil sur ce lien Reference c++, pour les fonctionnalités de références.

    Exemple de code pour ouvrir un fichier texte en lecture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include <iostream>
    #include <fstream>
    [...]
    filebuf fb;
    fb.open ("dataBase.txt",ios::in);
    istream is(&fb);     // Ceci est ton flux sur le fichier c'est à partir de lui que tu pourras faire des manipulations
    Pour lire les lignes de texte dans le fichier je te conseil la fonction getline qui renvoie un string

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    string ligne;
    getline( is,ligne );
    Ainsi le contenu de la ligne du fichier est stockée dans l'objet de type string. Aprés la classe string de la STL te permet tout un tas de manipulation (classe string

    Concernant le vecteur d'objet Matrix (matrix) tout dépend de ce que tu veux en faire. La fonction imput pourrait par exemple te renvoyer un pointeur sur le vecteur, ou bien tu peux le passer en référence à la fonction input qui le met à jour.
    Là il faut en dire un peu plus sur ce que tu veux faire exactement.

  6. #6
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Citation Envoyé par andnicam Voir le message
    Exemple de code pour ouvrir un fichier texte en lecture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include <iostream>
    #include <fstream>
    [...]
    filebuf fb;
    fb.open ("dataBase.txt",ios::in);
    istream is(&fb);     // Ceci est ton flux sur le fichier c'est à partir de lui que tu pourras faire des manipulations
    Euh… quel est l'intérêt de créer un « std::filebuf » si c'est pour l'utiliser via un « std::istream » ?
    C'est exactement comme créer directement un « std::{i,o}fstream », sauf que l'on a un objet de plus à gérer…

  7. #7
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Bonjour,

    Pour commencer, on n'inclut dans un fichier source que ce qui est nécessaire.
    Ça évite de créer des dépendances inutiles, et tout ce que ça implique…
    Donc quand tu veux utiliser la directive « #include », demande-toi si tu as besoin d'éléments déclarés dans le fichier à inclure dans le fichier source en cours d'écriture.
    Tu peux aussi te demander si le fichier que tu veux inclure n'est pas déjà inclus dans un des fichiers inclus.
    Tu devrais d'ailleurs le faire, lorsque tu écris un fichier d'implémentation (.cpp), pour les fichiers inclus dans le fichier d'en-tête (.h).

    Un petit exemple vaut bien une longue explication…
    toto.h
    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
    #ifndef TOTO_H
    #define TOTO_H
     
     
    #include <iostream>
    // Pas nécessaire, donc inutile, donc on supprime !
     
    #include <string>
    // Indispensable, donc on garde
     
     
    void titi(const std::string&);
     
     
    #endif // TOTO_H
    toto.cpp
    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
    #include <iostream>
    // Indispensable, donc on garde
     
    #include <string>
    // Indispensable, mais inclus dans le fichier « toto.h », donc on supprime !
     
    #include "toto.h"
    // Indispensable, donc on garde
     
     
    using namespace std;
     
    void titi(const string& s)
    {
        cout << "Le paramètre de la fonction est : " << s << endl;
    }

    Ensuite, on ne fait d'allocation dynamique que lorsque l'on en a vraiment besoin.
    L'allocation statique est beaucoup plus fiable et sûre, moins sujette aux erreurs, en particulier les fuites de mémoire.
    Pour ta variable dataBase du main, tu sais précisément de quelle manière et à quel moment elle va être créée, et tu n'en as pas besoin hors du scope de la fonction « main » ; alors une allocation statique est requise.
    Les deux instructions suivantes sont équivalentes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    string dataBase = "dataBase.txt";
    string dataBase("dataBase.txt");

    Maintenant, deux petites remarques.
    Lorsque l'on veut accéder à l'élément x du pointeur ptr, tu as compris qu'il faut écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (*ptr).x // Avec les parenthèses, c'est plus clair
    Mais il existe un raccourci d'écriture très pratique, et non ambigu :
    Il fonctionne aussi bien avec les attributs membres qu'avec les fonctions membres.

    Puisqu'il faut de toute façon passer le nom du fichier à ouvrir à la fonction « input() », il n'y a pas de raison de passer un pointeur.
    Donc une signature plus correcte serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void input(std::string dataBase);
    Sauf que dans ce cas, la chaîne de caractères va être dupliquée, ce qui n'est guère souhaitable.
    Pour pallier ce problème, le C++ introduit ce qu'on appelle les « références » (F.A.Q.) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void input(std::string& dataBase);
    Cette fois, la chaîne ne sera pas dupliquée.
    Mais elle n'est pas censée être modifiée dans la fonction, alors on rajoute le mot-clé « const » :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void input(const std::string& dataBase);

    L'utilisation des références est un casse-tête pour les débutants (pas que pour eux, d'ailleurs…).
    Alors si tu n'es pas à l'aise, tu peux continuer à utiliser des pointeurs dans un premier temps ; mais il faut que tu saches que ça existe, et comment ça s'utilise.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void input(const std::string *dataBase);

    Concernant la lecture d'un fichier, il va falloir te documenter sur les classes de type « fstream », et plus généralement sur les flux d'entrée/sortie (input/output streams).
    www.cppreference.com
    www.cplusplus.com
    Je vois que tu as déjà inclus le fichier d'en-tête, mais tu n'es pas allé jusqu'au bout.

    Si tu as d'autres questions, n'hésite pas.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    merci beaucoup tous d'avoir pris le temps de répondre (et pour vos longue réponses) mais je pense que je vais commencer petit à petit par des choses simples car je me rends compte que je ne maitrise pas grand chose.

    Dans un premier temps j'ai commencé par m'interesser à ce fichier texte (data.txt):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    # premier type de données
    matrix ferrite 2.85 1e-30
    matrix aluminium 1.85 1.2e-30
     
    # deuxieme type de données
    precipitate VC 4.1
    precipitate Mg2Si 4
    precipitate Mg5Si6 4.7
    Je vais essayer juste de lire mot pas mot le fichier et classer selon si le mot clef est matrix ou precipitate

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #include <iostream>
    #include <fstream>
    using namespace std;
    int main()
    {
        string mon_fichier = "data.txt";  // je stocke dans la chaîne mon_fichier le nom du fichier à ouvrir
        ifstream dataBase(mon_fichier.c_str(), ios::in);
        if(dataBase)  // si l'ouverture a réussi
        {
            while (!dataBase.eof()) //temps que l'on a pas tout lu
            {
                  if (!dataBase.eof())
                  {
                      string command, dump;
                      dataBase >> command;
     
                      if (command=="#")
                      {
                          getline(dataBase,dump);
                          cout << dump << endl;
                      }
                      else if (command=="matrix")
                      {
                          string MatrixName;
                          double LatticeParameter_M, AtomicVolume_M;
                          cout << "matrix command invoqued"  << endl;
                          dataBase >> command;
                          MatrixName = command;
                          dataBase >> command;
                          LatticeParameter_M = command;
                          dataBase >> command;
                          AtomicVolume_M = command;
                          cout << MatrixName << LatticeParameter_M << AtomicVolume_M << endl;
                       }
                       else if (command=="precipitate")
                       {
                          string PrecipitateName;
                          double LatticeParameter_P;
                          cout << "precipitate command invoqued"  << endl;
                          dataBase >> command;
                          PrecipitateName = command;
                          dataBase >> command;
                          LatticeParameter_P = command;
                          cout << PrecipitateName << LatticeParameter_P << endl;
                       }
                       else
                       {
                       }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else  // sinon
            {
                 cout << "Impossible d'ouvrir le fichier !" << endl;
            }
            dataBase.close();  // on ferme le dataBase
            return 0;
    }


    Ce programme "essaie" de mettre les parametre de matrice et precipitate dans des variables.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    le probleme (je crois) est que la variable commande est un string et que moi il me faut des doubles pour certains parametres

    voici l'erreur affichée

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    Je pense que je vais fermer ce poste car c'est "le bordel",
    je vais reprendre petit à petit mon probleme et je posserai des questions sur des points precis je pense que ca sera plus clair pour tous (y compris pour moi)

    merci beacoup tous de votre participation

    A+

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Tu devrais cependant prendre le temps de relire mon intervention à ton aise...

    Et surtout les commentaires, que j'ai pris soin de placer dans tout le code

    Tout ce que je dis te viendra bien à point, même si tu décide par la suite d'avancer "à petits pas"
    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

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Tu devrais cependant prendre le temps de relire mon intervention à ton aise...
    Et surtout les commentaires, que j'ai pris soin de placer dans tout le code
    Tout ce que je dis te viendra bien à point, même si tu décide par la suite d'avancer "à petits pas"
    oui koala je vais bien relire tous cela attentivement ne t'inquiete pas mais en parallele je vais essayer d'avancer à petit pas (car je me rend compte qu'il me manque pas mal de base pour comprendre ton intervention)

    merci en tout cas pour ton aide, c'est tres gentil

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

Discussions similaires

  1. Réponses: 20
    Dernier message: 01/11/2007, 13h52
  2. Comment lire un fichier et extraire des données
    Par salut93 dans le forum MATLAB
    Réponses: 14
    Dernier message: 12/06/2007, 11h27
  3. mettre fichiers avec déjà des données dans répertoire
    Par petitange_lili dans le forum Langage
    Réponses: 1
    Dernier message: 22/03/2007, 08h23
  4. Réponses: 1
    Dernier message: 23/12/2006, 23h39
  5. fichier CSV modification des données.
    Par suya95 dans le forum Excel
    Réponses: 8
    Dernier message: 26/07/2006, 12h22

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