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

Langage C++ Discussion :

Extraction/Insertion de données formatées dans un fichier texte


Sujet :

Langage C++

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

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

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 5
    Points
    5
    Par défaut Extraction/Insertion de données formatées dans un fichier texte
    Bonjour tout le monde,
    Je developpe une petite application en c++ qui permet d'envoiyer et recevir des messages sur une meme machine entre plusieurs utilisateurs (Simulation d'une boite mail)
    Enfait tous les messages des differents utilisatuers sont tous stocké dans un meme fichier texte formaté de la maniere suivante :

    DESTINATAIRE OBJET MESSAGE
    DESTINATAIRE OBJET MESSAGE

    Un message est ecrit sur une ligne, chaque champ est séparer par une tabulation.

    - Premiere question : Est ce que le formatage est bon ?
    - Deuxieme question : Je demande etape par etape à l'utilisateur de saisir l'objet de son message, puis le texte et enfin le destinataire.
    Voici le code :

    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
     
    		string des,objet,msg;
     
    		cout << "Veuillez Indiquez L'objet :" << endl;
    		cin >> objet;
    		cout << "Veuillez ecrire votre message :" << endl;
    		cin >> msg;
    		cout << "Destinataire :" << endl;
    		cin >> des;
     
    		ofstream f( "test.txt",ios_base::app);
     
    		if (!f.is_open())
    			cout << "Impossible d'ouvrir le fichier en écriture !" << endl;
    		else
    		{
    			f << des << " " << objet << "	" << msg << endl;
    		}
     
      f.close();

    Seulement ce code ne permet pas à l'utilisateur de saisir un texte avec des retour à la ligne, des espaces ...
    En plus l'objet de message peut aussi contenir des espace, or dans ce cas les espaces ne sont pas acceptés !


    3- Troisieme probleme :

    par exemple si je voudrais ouvrir les messages dont le destinaaire est X, comment je fais pour extraire juste les lignes du fichier dont le destinataire est X (dans notre cas qui commencent par X) ?
    j'ai essaiyé ce code, mais il repond pas à mes besoins :

    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
     
     
    		cout << "TEST" << endl; 
     
    		ifstream fichier("test.txt", ios::in);
     
    		if(fichier)  // si l'ouverture a fonctionné
            {
                    string contenu;  // déclaration d'une chaîne qui contiendra la ligne lue
                    getline(fichier, contenu);  // on met dans "contenu" la ligne
                    cout << contenu << endl;  // on affiche la ligne
                    getline(fichier, contenu);  // on met dans "contenu" la ligne
                    cout << contenu << endl;  // on affiche la ligne
     
                    fichier.close();
            }
            else
                    cerr << "Impossible d'ouvrir le fichier !" << endl;
     
    	}
    En l'attente de vos reponse, veuillez accepeter mes salytations distinguées.

  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,

    Il faut savoir qu'il y a un problème avec l'opérateur >> , c'est qu'il arrête la récupération une fois qu'il rencontre le premier caractère pouvant passer pour un espace.

    Les caractères de ce type sont, entre autre, l'espace (fatalement), la tabulation, le retour à la ligne et le caractère "fin de fichier".

    De plus, il faut savoir que, non content de s'arrêter au premier caractère pouvant être considéré comme un espace, il "supprime" du flux le caractère en question et... tout autre caractère pouvant passer pour un espace qui pourrait suivre, sans donner la possibilité de connaitre le ou les caractères supprimés.

    Or, s'il n'est pas impossible que le destinataire soit représenté sous la forme d'un seul mot (et encore, car, selon tes besoins ce peut être "Jean Gabin", ou pire encore "Monsieur le Président Directeur Général"), il y a de grandes chances pour que l'objet du message et le message prennent la forme de... phrases, voir de plusieurs phrases.

    Le résultat direct est qu'il est préférable dans ton cas de ne pas utiliser simplement cin>>des, cin>>objet ou cin>> msg, mais bien d'utiliser la fonction libre getline(flux, chaine) qui récupère par défaut dans la chaine "chaine" ce qui passe par le flux "flux" jusqu'au premier retour à la ligne ou, selon le cas, jusqu'au caractère de fin de flux.

    Autrement dit, cette fonction te permet de récupérer des phrases, ou du moins, plusieurs mots d'affilés.

    Ainsi, lorsqu'il est question de récupérer le destinataire, l'objet et le message, tu pourais utiliser un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    std::string msg;
    std::string objet;
    std::string des;
    cout << "Veuillez Indiquez L'objet :" << endl;
    std::getline(std::cin, objet);
    cout << "Veuillez ecrire votre message :" << endl;
    std::getline(std::cin, msg);
    cout << "Destinataire :" << endl;
    std::getline(std::cin, des);
    La deuxième conséquence de ce problème est qu'il est préférable de ne pas utiliser un caractère pouvant passer pour un espace comme caractère de séparation des différents champs dans ton fichier.

    Comme, de plus, un message peut être composé de n'importe quel signe de ponctuation "classique" (point, virgule, point virgule, apostrophes, guillemets, trait d'union, voire arobase ou underscore), il me semble opportun de sélectionner un caractère qui a en tout cas peu de chance d'être utilisé dans une conversation courante.

    Le caractère auquel je penserais directement est le pipe " | ", et c'est celui que je te conseillerais d'utiliser pour séparer les différents champs de ton fichier.

    En effet, la fonction getline autorise un troisieme argument qui correspond... au séparateur à utiliser pour représenter la fin de la saisie.

    Ainsi, l'écriture dans le fichier pourrait prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::ofstream ofs("fichier.txt");
    ofs<<des << '|'
       <<objet << '|'
       <<msg << '|'<<endl;
    et la lecture depuis le fichier prendrait alors la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    std::ifstream ifs("fichier.txt");
    std::string des;
    std::string objet;
    std::string msg;
    std::getline(ifs,des,'|');
    std::getline(ifs,objet,'|');
    std::getline(ifs.msg,'|');
    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
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

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

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Merci pour votre aide,

    mais j'ai deja un autre probleme !
    en utilisant le code que vous m'avez proposé pour la lecture :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    std::string msg;
    std::string objet;
    std::string des;
    cout << "Veuillez Indiquez L'objet :" << endl;
    std::getline(std::cin, objet);
    cout << "Veuillez ecrire votre message :" << endl;
    std::getline(std::cin, msg);
    cout << "Destinataire :" << endl;
    std::getline(std::cin, des);

    Je ne peux rien ecrire !
    les messages : Veuillez indiquer l'objet, Veuillez ecrire le msg .... s'affiche sans que l'utilisateur puisse entrer quoique soit !

    En l'attente de votre reponse veuillez accepter mes salutations distinguées.

  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
    Citation Envoyé par M3HD1 Voir le message
    Merci pour votre aide,

    mais j'ai deja un autre probleme !
    en utilisant le code que vous m'avez proposé pour la lecture :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    std::string msg;
    std::string objet;
    std::string des;
    cout << "Veuillez Indiquez L'objet :" << endl;
    std::getline(std::cin, objet);
    cout << "Veuillez ecrire votre message :" << endl;
    std::getline(std::cin, msg);
    cout << "Destinataire :" << endl;
    std::getline(std::cin, des);

    Je ne peux rien ecrire !
    les messages : Veuillez indiquer l'objet, Veuillez ecrire le msg .... s'affiche sans que l'utilisateur puisse entrer quoique soit !
    Voilà bien quelque chose de bizarre, car, chez moi, cela fonctionne parfaitement...

    Pourrais-je avoir le code exact que tu utilise
    En l'attente de votre reponse veuillez accepter mes salutations distinguées.
    Juste au passage, je ne suis pas encore vieux assez pour être vouvoyé (mais aurais-je même soixante ans, je crains que je ne le serais pas ), et puis, un forum est, par définition, un endroit sensé être convivial...

    Tu peux donc éviter les salamalec
    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
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

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

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Voici le code que j'utilise
    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
     
     
    #include "EcrireMail.h"
    #include <iostream>
    #include <fstream>
    #include <string>
     
    using namespace std;
     
     
     
    	void EcrireMail::enregistrer(){
     
    		string des,objet,msg;
     
     
    cout << "Veuillez Indiquez L'objet :" << endl;
    std::getline(std::cin, objet);
    cout << "Veuillez ecrire votre message :" << endl;
    std::getline(std::cin, msg);
    cout << "Destinataire :" << endl;
    std::getline(std::cin, des);
     
    		ofstream f( "test.txt",ios_base::app);
     
    		if (!f.is_open())
    			cout << "Impossible d'ouvrir le fichier en écriture !" << endl;
    		else
    		{
    			f << des << " " << objet << "	" << msg << endl;
    		}
     
      f.close();
     
    	}
    apres le 1er cout :Veuillez indiquer l'objet, le programme passe directement au 2eme cout : Veuillez ecrire le msg ! et il prend le message et le met dans la variable message, idem pour la variable destinataire.
    J'ai remarqué qu'il y a un probleme juste avec la premiere getline !


    Enfait j'ai trouvé un bout de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
     
    	       	        string s;
    			char c = cin.peek();
    			if (c == '\n' || c == '\r')
    			cin.get(c);
    			// lire une ligne à l'entrée standard, la mettre dans s
    			getline (cin, s);
    			cout << s << endl;
    Je l'ai pas bien compris, mais il sert a mettre toute une phrase (avec les espace dans une chaine de caractere) jusque là je suis arrivé à prendre tout une phrase, ça me suffit pour l'objet et le destinaiataire, seulement pour les message j'aimerai pouvoir permettre à l'utilisateur d'utiliser tout (tab, espace, retour à la ligne ... ) mais je ne comprend plus comment je vais detecter la fin du message ni dans quel genre de variable le mettre avant de le tranferer au fichier ?!


    Merci

  6. #6
    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
    Je te conseillerais de travailler "point par point", et de vérifier une chose après l'autre si tout se passe bien.

    Ainsi, chez moi (et, normalement chez tout le monde), un code demandant à l'utilisateur d'introduire les différentes informations sous une forme proche 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
    #include <iostream>
    #include <string>
    int main()
    {
    std::string msg;
    std::string objet;
    std::string des;
    cout << "Veuillez Indiquez L'objet :" << endl;
    std::getline(std::cin, objet);
    cout << "Veuillez ecrire votre message :" << endl;
    std::getline(std::cin, msg);
    cout << "Destinataire :" << endl;
    std::getline(std::cin, des);
    // un affichage, pour s'assurer que tout a bel et bien été pris en compte
    std::cout<< "message destine a :"<<des<<std::endl
    		 << "objet : "<<objet<<std::endl
    		 <<"message : "<<std::msg;
     
        return 0;
    }
    devrait fonctionner sans aucun problème

    L'étape suivante consistant à essayer d'écrire les informations dans un fichier, et, pour se faire, il "suffira" de remplacer l'envoi vers la sortie standard (std::cout<<) par... le flux de fichier en sortie correspondant (en l'adaptant de telle sorte que tout se retrouve sur une ligne et que les différents champs soient séparés, comme je l'ai conseillé plus tôt, par des pipes, par exemple)

    Je ne sais pas où tu as pu trouver le bout de code à base de cin.peek, mais, en toute honnêteté, je ne le trouve ni efficace ni intéressant
    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

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

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

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Je suis desolé mais j'ai changé mon message au meme moments que tu m'avais repondu, enfait j'ai un probleme juste avec la premiere getline !! j'ai meme essayer de mettre n'importe quoi juste avant la premiere getline(genre un cin pour prendre un entier) et comme ça elle marche bien !! mais en utilisant une getline au debut elle ne marche pas ?!

    Devrais je te signaler que j'utilise un menu au debut de l'application avec des choix, dans notre cas l'utilisateur dois saisir 1 pour :
    1- ecrire un message

    et dans le swich je cree une instance de la classe EcrireMail. voici le code :
    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
     
    #include "BoiteMail.h"
    #include "EcrireMail.h"
    #include "LireMail.h"
    #include <iostream>
     
    using namespace std;
     
     
     
    	void BoiteMail::menu(){
    	int choix=0;
    	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    	cout << "~~~~~~ Bienvenu sur votre boite mail ~~~~~~" << endl;
    	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    	cout << "~~~~~~ 1. Ecrire un e-mail ~~~~~~~~~~~~~~~~" << endl;
    	cout << "~~~~~~ 2. Consulter boite de reception ~~~~" << endl;
    	cout << "~~~~~~ 3. Consulter boite d'envoi ~~~~~~~~~" << endl;
    	cout << "~~~~~~ 4. Quitter ~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    	cin >> choix;
     
    	switch(choix)
    	{
    	case 1:
    		EcrireMail A;
    		A.enregistrer();
    		break;
     
    	case 2:
    		LireMail B;
    		B.ouvrir();
    		break;
     
    	case 4:
    		cout << "Merci pour votre visite"<< endl;
    		break;
     
    	}
     
     
     
    	}
    et la c'est la classe EcrireMail :

    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
     
    #include "EcrireMail.h"
    #include <iostream>
    #include <fstream>
    #include <string>
     
    using namespace std;
     
     
     
    	void EcrireMail::enregistrer(){
     
    string msg;
    string objet;
    string des;
     
    cout << "Veuillez Indiquez L'objet :" << endl;
    getline(cin, objet);
    cout << "Veuillez ecrire votre message :" << endl;
    getline(cin, msg);
    cout << "Destinataire :" << endl;
    std::getline(cin, des);
     
    std::cout<< "message destine a :"<<des<<endl;
    		cout << "objet : "<<objet<<endl;
    		cout <<"message : "<<msg;
     
    ofstream f( "test.txt",ios_base::app);
     
    		if (!f.is_open())
    			cout << "Impossible d'ouvrir le fichier en écriture !" << endl;
    		else
    		{
    			f << des << "|" << objet << "|" << msg << endl;
    		}
     
      f.close();
     
     
     
    	}

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

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

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    C'est vraiment bizarre mais en ajoutant une getline qui ne sert à rien ça marche !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    getline(cin, objet);
     
    cout << "Veuillez Indiquez L'objet :" << endl;
    getline(cin, objet);
    cout << "Veuillez ecrire votre message :" << endl;
    getline(cin, msg);
    cout << "Destinataire :" << endl;
    std::getline(cin, des);
    Seulement j'aime pas ce genre de solution mystere !!

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

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

    Informations forums :
    Inscription : Décembre 2009
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Je résume :

    1-J'ai un probleme avec la toute premiere getline : comme si elle n'existait pas !
    2-Avec ce code l'utilisateur peut taper des phrases dans le messages mais sans retour à la ligne ! cepenant un message peut contenir des retour à la ligne, or dés que l'utilisateur tape sur ENTRER on passe à l'etape suivante ! y a t'il une solution pour remedier à ça ?
    3-Lors de la lecture du fichier, si un utilisateur X ouvre l'application et choisit de consulter la boite de reception, je voudrais lui afficher les messages dont le destinaires est X. Je procederai donc à une recherche dans le fichier en lisant juste le premier mot de chaque ligne (la pipe sera alors le separateur) seulement je ne trouve pas comment me deplacer d'une ligne apres avoir lu le premier destinataire ?!
    4-Je voudrais savoir comment lire le deusieme champ par exemple dans une ligne (les champs dans une ligne sont separés par une pie comme prevu)


    En l'attente de vos reponses, veuillez accepter mes salutations distinguées.

Discussions similaires

  1. Réponses: 3
    Dernier message: 10/06/2007, 14h59
  2. extraction de données formatées dans un fichier excel
    Par slausseur dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 14/03/2007, 15h00
  3. Réponses: 3
    Dernier message: 04/01/2007, 17h42
  4. Transposer des données sql dans un fichier texte
    Par Anakior dans le forum Outils
    Réponses: 3
    Dernier message: 11/12/2005, 10h01
  5. Réponses: 6
    Dernier message: 02/06/2005, 12h44

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