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 :

[AIDE] modification d'un fichier texte


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 94
    Points : 44
    Points
    44
    Par défaut [AIDE] modification d'un fichier texte
    Bonsoir,

    j'ai un souci avec un mode écriture qui va modifier un fichier texte qui est de la forme : Nom;Qantite_Actuelle;Nb_Dose;Quantite_Max

    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
     
    cafe;1000000;1;1000000
    the_vert;1000000;1;1000000
    the_noir;1000000;1;1000000
    the_citron;1000000;1;1000000
    cacao;1000000;1;1000000
    sucre;1000000;1;1000000
    lait;1000000;1;1000000
    potage_tomate;1000000;1;1000000
    potage_celeri;1000000;1;1000000
    potage_poulet;1000000;1;1000000
    eau;1000000;1;1000000
    batonnet;10000;1;10000
    gobelet;10000;1;10000
    sel;1000000;1;1000000
    et voila ma 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
     
    void Ingredient::Consommer(int Nb_Dose)
    {
    	char* Nom=NULL;
    	string Nom_Bis;
    	Nom_Bis=this->Get_Nom();
    	strcpy(Nom,Nom_Bis.c_str());
    	if(Nom!="eau") {
     
    	//-> écrire dans le fichier texte : Ingredient.txt et effectuer cette operation : Quantite_Actuelle = Quantite_Actuelle - Nb_Dose*Qte_Dose;???
     
    	}
     
    }

    merci du coup de pouce.

  2. #2
    Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 94
    Points : 44
    Points
    44
    Par défaut
    En PJ, je vous ai mis toute ma classe distributeur.
    Fichiers attachés Fichiers attachés

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Ce code n'est ni fait ni à faire, ni en C ni en C++.
    En C++, on ne s'embarrasse pratiquement jamais avec les char*, les string suffisent.
    Par quel mécanisme mental bizarre as-tu eu l'idée de recopier ta string dans un char* pour faire ta comparaison, au lieu d'utiliser directement la string ?

  4. #4
    Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 94
    Points : 44
    Points
    44
    Par défaut
    voila pourquoi j'ai fait un char* au lieu d'un string !! Ci-joint l'erreur que j'obtiens avec un string :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    error C2664: 'strcpy' : cannot convert parameter 1 from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'char*
    Fichiers attachés Fichiers attachés

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Le problème, c'est que tu n'avais pas non plus besoin du strcpy() pour faire ta comparaison...

  6. #6
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par babap1 Voir le message
    voila pourquoi j'ai fait un char* au lieu d'un string !! Ci-joint l'erreur que j'obtiens avec un string :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    error C2664: 'strcpy' : cannot convert parameter 1 from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'char*
    Tu devrais lire la FAQ sur les string ! http://cpp.developpez.com/faq/cpp/?page=strings

    En C++ on n'utilise les char* que vraiment quand on a pas le choix! Jette un coup d'oeil à la FAQ, et tout s'éclaircira !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    J'ai bien peur que je ne serai pas beaucoup plus agréable que mes prédécesseurs, mais il y a réellement beaucoup de place pour le progrès dans les deux fichiers de code que tu nous a fournis.

    La règle de base, si tu veux programmer en C++, c'est de n'utiliser QUE le C++, et de ne te tourner vers des structures ou fonctions C que si tu ne peux vraiment pas faire autrement

    Ainsi, les directive #define sont, autant que faire se peut, à éviter, et celle qui me chagrine le plus est sans nul doute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define APP_PATH "D:\\Documents and Settings\\Administrateur\\Bureau\\Projet_Machine_Cafe\\Fichiers_Texte\\"
    En toute logique, la chaine de caractères qu'elle représente n'est nécessaire que dans la classe Distributeur, mais devra sans doute être commune à toutes les instances de Distributeur.

    On peut donc estimer que cette chaîne de caractères est une bonne candidate pour devenir ce que l'on appelle un membre de classe (par opposition à un membre d'instance) de la classe Distributeur, et qu'elle peut être constante

    Pour déclarer un membre de classe, le mot magique est "static" (cf Les entrées de la FAQ qui s'y rapportent), et cela prendrait sans doute la forme d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static const std::string app_path;
    déclaré en privé dans la classe Distributeur et d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const std::string Distributeur::app_path="D:\\Documents and Settings\\Administrateur\\Bureau\\Projet_Machine_Cafe\\Fichiers_Texte\\"
    dans Distributeur.cpp

    De plus, il est important de penser à donner la préférence aux références (constantes si besoin) lorsque tu passe des paramètres, et, très souvent également lorsque tu renvoie un objet qui "survit" à l'appel de la fonction qui le renvoie...

    Ainsi, le parametre string de tes méthode get_quelquechose et construire_quelquechose est un candidat idéal pour l'utilisation des référence constante (étant entendu que la chaine de caractères que tu passe en paramètre n'a a priori aucune raison d'être modifiée par la fonction qui la reçoit)

    Ensuite, tu semble faire le distingo entre un "Lot_Piece", une "Boisson" et un "Ingredient", or, si j'ai bien compris, tu nous parle ici d'un distributeur automatique, et, à son niveau, on pourrait estimer que tout n'est que ElementDeStock, par exemple...

    En effet, pour le Distributeur, il a n ingredients (qui se subdivisent sans doute ne n1 doses de cafe, n2 doses de chocolat, n3 dose de the, n4 doses de potage, n5 doses de supplément de lait, ...), m gobelets, o petites cuillères, et même p quantité d'eau (bien qu'il soit, vraisemblablement, relié à la distribution d'eau ), et, ce qu'il va faire c'est, à peu près dans l'ordre
    • sortir un gobelet
    • sortir une dose de café (ou de the, de chocolat ou de potage)
    • sortir une dose de supplément de sucre (si demandé)
    • sortir une dose de supplément de lait (si demandé)
    • sortir une dose d'eau
    • sortir une petite cuillère

    et, pour lui, cela revient, tout simplement, à "sortir 6 fois un élément de son stock"

    L'avantage de tout cela, c'est que tu pourras profiter à fond du polymorphisme, et en arriver à envisager un conteneur qui te permettra de retrouver plus rapidement l'élément de stock que tu veux...

    En effet, le C++ fournit de base un tableau associatif: la map, disponible par inclusion du fichier d'en-tête <map> dans l'espace de nommage std, qui semble etre un candidat idéal pour maintenir au sein de ton Distributeur l'ensemble de ce qu'il contient, et dont la déclaration sous la forme (en tant que membre privé) de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /* La chaine sert de clé pour la recherche, et n'est rien d'autre
     * que le nom de tous les éléments de stock (cafe, the...)
     */ 
    std::map<std::string,ElementDeStock*> stock;
    remplacera avantageusement les trois tab_quelquechose que tu a fournis.

    En effet, il te suffira alors, pour la méthode, devenue unique, "getElementDeStock" de faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ElementDeStock* Distributeur::getElementDeStock(const std::string& name)
    {
         std::map<std::string, ElementDeStock*>::iterator it=stock.find(name);
         /* c'est peut etre un élément qui n'est pas (ou plus) de stock ...
          * dans ce cas, on renvoi NULL
          */
        if(it=stock.end())
            return NULL;
        /* sinon, on renvoie l'élément sélectionné */
        return (*it).second;
    }
    (avis au puristes: je sais, les chaînes de caractères en tant que clé, c'est moyen moyen, mais ici, cela semble être la moins mauvaise solution )

    Il y a tellement à dire sur le code que tu présente que j'en viendrais presque à écrire tout un roman pour reprendre tous les points de conceptions qui sont à revoir, et donc, je vais me contenter de te donner le "coup de pousse" qui concerne la question initialement posée...

    Comme indiqué au début du message, veille à n'utiliser en C++ QUE ce qui est C++...

    Il faut donc éviter tout ce qui est fgets, strcpy, strcmp, FILE* et bien d'autre encore, car, pour la gestion de fichiers, le C++ fournit deux classes bien plus facile d'emploi: ifstream (fichiers en lecture) et ofstream (fichiers en écriture), toutes les deux accessibles par inclusion du fichier <fstream> dans l'espace de nommage std.

    Tu trouvera un tas d'information sur l'utilisation de ces classes dans la section de la FAQ qui y est consacrée, mais en gros, pour lire ton fichier, tu pourrait te contenter (au fait, le ; n'est pas le meilleur séparateur que tu pouvais choisir: avec un ifstream, tu peux parfaitement laisser simplement un espace ) d'un

    (c'est crade, mais cela pourra aller, avec des espace entre les 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
    18
    19
    20
     
    std::string nomfich;
    /* construction de la chaine nomfich */
    std::string nom;/*le Nom */
    int qa; /* la Qantite_Actuelle*/
    int nbd; /*le Nb_Dose*/
    int qm;/* laQuantite_Max */
    std::ifstream ifs(nomfich.c_str())
    if(ifs)
    {
        while(ifs>>nom)
        {
            ifs>>qa>>nbd>>qm;
            /*"yapuka" créer l'objet... */
       }
    }
    else
    {
        //le fichier n'est pas ouvert,y a peut etre quelque chose à faire ;)
    }
    Pour ce qui est de l'écriture, il faut savoir qu'un fichier est quelque chose de "gravé dans le marbre"...

    On peut éventuellement rajouter quelque chose à la fin (en l'ouvrant en mode "append"), mais, si tu veux modifier les données, il faut "casser la pierre", et tout recommencer à zéro...

    Ici, il faudra donc réécrire à chaque fois le fichier en entier (ce qui pourrait te permettre de créer des fichiers "datés", ce qui ne serait peut etre pas plus mal, histoire d'avoir un "historique" ), et cela se ferait sous 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
     
    std::string nomfich; /* le nom du fichier à utiliser */
    /* construction du  nom de fichier */
    std::ofstream ofs(nomfich.c_str());
    if(ofs)
    {
        /* on est parti sur une std::map<std::string, ElementDeStock*>
         * nommee stock
         */
        for(std::map<std::string, ElementDeStock*>::iterator it=stock.begin();
             it!=stock.end();it++)
        {
            ofs<< (*it).first<<" "<
               <<(*it).second->getRestant()<<" "
               <<(*it).second->getQuantite()<<" "
               <<(*it).second->getMax();
        }
    }
    else
    {
        /* le fichier n'est pas ouvert, il y a peut etre quelque chose à faire ? */
    }
    où, tu l'aura sans doute compris, getRestant(), getQuantite() et getMax() sont des comportements génériques qui peuvent s'appliquer à un élément de stock et qui fournissent respectivement la quantite actuelle, le nombre de doses et la quantité maximale

Discussions similaires

  1. Réponses: 50
    Dernier message: 19/10/2007, 23h38
  2. aide modification d'un fichier en c
    Par laroche1 dans le forum C
    Réponses: 15
    Dernier message: 01/05/2007, 01h18
  3. modification d'un fichier texte
    Par didy59 dans le forum C
    Réponses: 2
    Dernier message: 25/11/2006, 11h38
  4. Modification d'un fichier texte
    Par velo83 dans le forum C
    Réponses: 14
    Dernier message: 21/05/2006, 07h28
  5. Réponses: 4
    Dernier message: 21/04/2006, 21h55

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