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 texte pré-formaté


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 14
    Par défaut Lire un fichier texte pré-formaté
    Voila je souhaite lire un texte près formaté, qui sépare les différentes données par ";".
    Pour vous en donner un aperçue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    "Abramites hypselonotus";"Günther, 1868";"Anostomidés";"23";"27";"0";"6.0";"7.5";"0.0";"4";"15";"0";"14.0";"14.0";"?";"Milieu & Inférieure";"Bassins de l'Amazone et de l'Orénoque";"Herbivore, il risque de manger les plantes de l'aquarium s'il est mal nourri.Lui fournir de la nourriture vegetale souvent pour eviter un carnage aux plantes.
    ";"non déterminé (oeil nu)";
    Actuellemt, je ne sais utiliser que ifstream pour ouvrir mon fichier et j'utilise les flux pour attribuer les valeurs :
    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
     
    ifstream fichier("poissons.txt"); // ouverture du fichier
            if ( fichier ) // ce test échoue si le fichier n'est pas ouvert
        {
            int nbrpoissons; // variable contenant le nombre de poissons donné au début du fichier.
                    fichier >> nbrpoissons;
                    cout << "il y a "<<nbrpoissons<<" poissons dans la BDD.";
                    string texte; // variable contenant le texte lu
                    // cette boucle s'arrête dès qu'une erreur de lecture survient
                    int count = 0;
                    while (!fichier.eof())
                    {
                            fichier >> texte;
                            poissons[count]->setnom( texte );
                            count++;
                    }
          }

    Mais voila le problème c'est que cette méthode ne coupe pas aux bons endroits(";"). En effet elle coupe le texte au niveau des espaces!!

    En C j'aurais utilisé un scanf, mais en C++, je ne sais pas comment faire.

    Si quelqu'un a une idée, je suis preneur.
    Merci de m'avoir lu en tout cas ;-)

  2. #2
    Membre Expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Par défaut
    Salut,

    Plutôt qu'utiliser eof() pour voir si tu peux continuer à lire, utilise la méthode good(). Elle ne renvoie vrai que si tout les flags d'erreurs sont "clean".
    Ensuite, pour lire tes lignes, utilise plutôt std::getline, ensuite tu coupe la ligne à chaque point virgule. Regarde la FAQ C++, il me semble qu'il y a un exemple de lecture de fichier texte, ça te montrera un peu mieux la voie à suivre.

  3. #3
    Membre averti
    Inscrit en
    Décembre 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 55
    Par défaut
    en effet, l'opérateur >> a pour délimiteur le caractère d'espacement. Il faut donc redéfinir ton opérateur

    Question: pourquoi ne pas utiliser les expressions régulières ou utiliser qqche comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    std::string st;
    while (getline(std::cin,st,';'))
    {
      //actions
    }
    A+

    JC

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Pour analyser un texte, il y a plusieurs techniques :
    - créer un analyseur à la main
    - créer une grammaire, puis un utilitaire qui générera automatiquement l'analyseur

    La deuxième solution a de nombreux avantages sur la première.
    En particulier, il devient bien plus facile d'étendre la syntaxe, et on est certain que l'analyseur est correct. On pourra même valider l'entrée en fonction de la grammaire.
    Par contre, il est fort possible que cela ne soit pas autant optimisé qu'un analyseur écrit à la main avec attention.
    Un autre désavantage c'est que les grammaires tombent dans un certain nombre de catégories. Et que certaines syntaxes ne peuvent pas être exprimées par des grammaires simples.

  5. #5
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 14
    Par défaut
    Tout d'abord merci pour vos deux commentaires, j'en prend bonne note.
    En revanche il me reste une petite question :
    il y a des retour à la ligne dans certaine chaîne de caractères que je veux conserver.
    Est ce qu'un getline accompagné d'une redéfinition du délimiteur "getline(std::cin,st,';')" ne va pas me couper ces chaînes de caractères?

  6. #6
    Membre Expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Par défaut
    Si. Dans ce cas, il faudra soit que tu lises tout, et que tu parses les chaînes pour savoir si elle sont continuées sur la ligne suivante, soit (solution plus facile), encoder les retours à la ligne à l'écriture du fichier par un délimiteur à toi.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    Ceci dit, à voir l'exemple de chaine que tu propose, je présume qu'il s'agit d'information concernant une "chose" bien précise...

    A vue d'oeil, je pencherait pour une description d'espece fournissant le nom scientifique, la personne ayant découvert l'espece, la classe de l'espece, ainsi que la plupart de ses caractéristiques...

    Il me semblerait donc intéressant, si ce n'est pas encore fait, de créer une structure ou une classe regroupant, justement, l'ensemble de ces caractéristiques, afin de se faciliter la vie...

    Cela pourrait prendre la forme 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
     
    struct espece
    {
        std::string nom;
        std::string decouvert;
        std::string classe;
        int entier1;/* comme je ne sais pas à quoi correspondent les chiffres :P */
        int entier2;
        int entier3;
        float reel1;
        float reel2;
        float reel3;
        int entier4;
        int entier5;
        int entier6;
        float reel4;
        float reel5;
        type data15;
        std::string chaine4; //(ca représente quoi, milieu et inférieur?)
        std::string habitat;
        std::string remarques;
        std::string observation;
    };
    à L'écriture dans le fichier (si tu dois encore le faire), il te suffira d'écrire chaque membre, en les séparant par des ; et, à la lecture, de lire systématiquement chaque membre en s'arretant au ; en se basant sur le fait que les membres de la classe seront entièrement écrits, ou ne le seront pas du tout

    J'en profite pour signaler que le fait de choisir d'entourer les valeurs de guillemets dans le fichier n'est pas forcément la meilleure idée qu'on puisse avoir...

    Au pire, si certaines chaines de caractères sont susceptibles de contenir des ;, tu peux te tourner vers des caractères plus rarement utilés comme séparateur: | & ou $ ... voir en choisir un pour représenter le retour à la ligne (qu'il te suffira de convertir en \n<-->caractère choisi apres lecutre ou avant écriture )
    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

  8. #8
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 14
    Par défaut
    Oui en fait j'ai déjà créer une classe qui reçoit toutes ces informations.
    Et il faut savoir que ce n'est pas moi qui ai écris ce fichier, je le récupère sur internet, c'est une base de données contenant des informations sur les poissons d'ornements.
    Et j'ai effectivement fini par choisir le type de solution que tu me propose à savoir :
    1) retravailler le fichier :
    Je remplace toutes les chaînes ";" par le caractère | .
    2) je lis le fichier à l'aide de std::getline en spécifiant le délimiteur et j'insère simultanément l'objet string retourné dans ma variable.

    ce pendant il me reste à trouver comment convertir un string en float. Je sais déjà le faire pour des int :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    strtol(texte.c_str(),NULL,10)
    //texte contient l'objet string retourné par std::getline;
    //le deuxième paramètre est un pointeur sur le dernier élément de la chaîne de caractère convertie. Permettra plus tard de vérifier la conversion;
    //10 indique que l'on travaille sur une base décimale.
    Mais cette question pourra faire l'objet d'un nouveau sujet si je ne trouve pas de solutions.

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

Discussions similaires

  1. lire un fichier texte avec different format
    Par najma dans le forum MATLAB
    Réponses: 6
    Dernier message: 26/04/2011, 12h37
  2. Comment écrire un fichier texte au format MS-DOS ?
    Par fredfred dans le forum Langage
    Réponses: 9
    Dernier message: 20/01/2005, 09h00
  3. Réponses: 1
    Dernier message: 24/11/2004, 16h54
  4. [Fichier] Lire un fichier texte long
    Par _Eric_ dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 18/08/2004, 15h22
  5. Réponses: 2
    Dernier message: 26/05/2004, 17h53

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