Modification dans un fichier texte en c++
Résolu/Fermé
yannboensit2007
Messages postés
67
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
10 mai 2010
-
10 mai 2007 à 19:48
yannboensit2007 Messages postés 67 Date d'inscription jeudi 10 mai 2007 Statut Membre Dernière intervention 10 mai 2010 - 15 mai 2007 à 16:34
yannboensit2007 Messages postés 67 Date d'inscription jeudi 10 mai 2007 Statut Membre Dernière intervention 10 mai 2010 - 15 mai 2007 à 16:34
A voir également:
- Modification dans un fichier texte en c++
- Fichier rar - Guide
- Comment ouvrir un fichier epub ? - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier host - Guide
- Ouvrir un fichier .bin - Guide
5 réponses
mamiemando
Messages postés
33344
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
7 novembre 2024
7 803
11 mai 2007 à 14:20
11 mai 2007 à 14:20
En fait je pense que c'est une mauvaise approche (enfin c'est moins point de vue). Globalement l'accès à un fichier est lent, donc il vaut mieux charger le fichier dans une structure de donnée, manipuler cette structure, et réécrire le fichier si nécessaire.
Si tu veux faire une fonction de modification en fonction du matricule, pense à corriger en conséquence les 3 maps de datas_etudiant_t. En toute rigueur la fonction ajouter_etudiant doit vérifier que personne n'a déjà cet identifiant.
Bonne chance
#include <map> #include <iostream> #include <fstream> #include <set> #include <string> typedef std::string matricule_t; typedef std::string nom_t; typedef std::string prenom_t; class datas_etudiant_t{ protected: typedef std::map<matricule_t,std::pair<nom_t,prenom_t> > map_matricule_t; typedef std::map<nom_t,std::set<matricule_t> > map_nom_t; typedef std::map<prenom_t,std::set<matricule_t> > map_prenom_t; map_matricule_t map_matricule; map_nom_t map_nom; map_prenom_t map_prenom; public: // Le constructeur datas_etudiant_t(){} // Ajouter un étudiant void ajouter_etudiant( const matricule_t & matricule, const nom_t & nom, const prenom_t & prenom ){ map_matricule[matricule] = std::make_pair(nom,prenom); map_nom[nom].insert(matricule); map_prenom[prenom].insert(matricule); } // Recherche sur le matricule bool trouver_matricule( const matricule_t & matricule, nom_t & nom, prenom_t & prenom ){ map_matricule_t::const_iterator fit(map_matricule.find(matricule)); if (fit == map_matricule.end()) return false; nom = (fit->second).first; prenom = (fit->second).second; return true; } // Recherche sur le prenom bool trouver_prenom( const prenom_t & prenom, std::set<matricule_t> & matricules ){ map_prenom_t::const_iterator fit(map_prenom.find(prenom)); if(fit == map_prenom.end()) return false; matricules = fit->second; return true; } // Recherche sur le nom bool trouver_nom( const nom_t & nom, std::set<matricule_t> & matricules ){ map_nom_t::const_iterator fit(map_nom.find(nom)); if(fit == map_nom.end()) return false; matricules = fit->second; return true; } template <typename Tstream> void write(Tstream & out) const{ map_matricule_t::const_iterator mit(map_matricule.begin()),mend(map_matricule.end()); for(;mit!=mend;++mit){ const matricule_t & matricule = mit->first; const nom_t & nom = (mit->second).first; const prenom_t & prenom = (mit->second).second; out << matricule << '\t' << nom << '\t' << prenom << std::endl; } } }; int main(){ datas_etudiant_t datas; datas.ajouter_etudiant("AP123","Poulain","Amélie"); datas.ajouter_etudiant("AP124","Mauresmo","Amélie"); datas.ajouter_etudiant("SP69","Poulain","Super"); datas.ajouter_etudiant("PP99","Parker","Peter"); { const std::string prenom_cherche = "Amélie"; std::cout << "rechercher " << prenom_cherche << std::endl; std::set<matricule_t> matricules; if(datas.trouver_prenom(prenom_cherche,matricules)){ std::set<matricule_t>::const_iterator sit(matricules.begin()),send(matricules.end()); for(;sit!=send;++sit) std::cout << *sit << std::endl; }else std::cout << "Pas de personne dont le prénom est " << prenom_cherche << std::endl; } { const std::string nom_cherche = "Poulain"; std::cout << "rechercher " << nom_cherche << std::endl; std::set<matricule_t> matricules; if(datas.trouver_nom(nom_cherche,matricules)){ std::set<matricule_t>::const_iterator sit(matricules.begin()),send(matricules.end()); for(;sit!=send;++sit) std::cout << *sit << std::endl; }else std::cout << "Pas de personne dont le nom est " << nom_cherche << std::endl; } // Ecrire dans la console datas.write(std::cout); // Ecrire dans un fichier std::ofstream ofs("plop.txt"); if(ofs){ datas.write(ofs); ofs.close(); }else std::cerr << "fichier invalide" << std::endl; return 0; }
Si tu veux faire une fonction de modification en fonction du matricule, pense à corriger en conséquence les 3 maps de datas_etudiant_t. En toute rigueur la fonction ajouter_etudiant doit vérifier que personne n'a déjà cet identifiant.
Bonne chance
yannboensit2007
Messages postés
67
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
10 mai 2010
11 mai 2007 à 20:13
11 mai 2007 à 20:13
j'aimerais savoir comment créer une fonction de modification et de suppression en utilisant maps datas_etudiant_t
mamiemando
Messages postés
33344
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
7 novembre 2024
7 803
11 mai 2007 à 21:04
11 mai 2007 à 21:04
Je pense qu'il te manque un pré-requis important : la STl, en particulier les std::map et les std::set ! Donc voici un peu de lecture :
https://community.hpe.com/t5/custom/page/page-id/HPPSocialUserSignonPage?redirectreason=permissiondenied&referer=https%3A%2F%2Fcommunity.hpe.com%2Ft5%2FServers-Systems-The-Right%2FSGI-com-Tech-Archive-Resources-now-retired%2Fba-p%2F6992583
https://community.hpe.com/t5/custom/page/page-id/HPPSocialUserSignonPage?redirectreason=permissiondenied&referer=https%3A%2F%2Fcommunity.hpe.com%2Ft5%2FServers-Systems-The-Right%2FSGI-com-Tech-Archive-Resources-now-retired%2Fba-p%2F6992583
Pour la suppression :
- dans map_matricule : il suffit d'écraser l'ancienne valeur
- pour les deux autres : rechercher le prénom (nom) avec un find, s'il est trouvé, supprimer le matricule du std::set correspondant. Je te laisse manipuler un peu tout ça pour ta familiariser avec la stl mais concrètement c'est moins de 20 lignes de code... Si tu comprends bien le code que je t'ai donné tu devrais y arriver, il suffit de prendre le temps de lire les deux liens que je t'ai donné. Voilà le début à rajouter dans la classe datas_etudiant_t
Pour une modification il suffit de faire une suppression suivie d'un ajout. Dans la classe datas_etudiant_t :
En cas de soucis n'hésite pas à repasser.
Bonne chance
https://community.hpe.com/t5/custom/page/page-id/HPPSocialUserSignonPage?redirectreason=permissiondenied&referer=https%3A%2F%2Fcommunity.hpe.com%2Ft5%2FServers-Systems-The-Right%2FSGI-com-Tech-Archive-Resources-now-retired%2Fba-p%2F6992583
https://community.hpe.com/t5/custom/page/page-id/HPPSocialUserSignonPage?redirectreason=permissiondenied&referer=https%3A%2F%2Fcommunity.hpe.com%2Ft5%2FServers-Systems-The-Right%2FSGI-com-Tech-Archive-Resources-now-retired%2Fba-p%2F6992583
Pour la suppression :
- dans map_matricule : il suffit d'écraser l'ancienne valeur
- pour les deux autres : rechercher le prénom (nom) avec un find, s'il est trouvé, supprimer le matricule du std::set correspondant. Je te laisse manipuler un peu tout ça pour ta familiariser avec la stl mais concrètement c'est moins de 20 lignes de code... Si tu comprends bien le code que je t'ai donné tu devrais y arriver, il suffit de prendre le temps de lire les deux liens que je t'ai donné. Voilà le début à rajouter dans la classe datas_etudiant_t
bool supprimer_etudiant(const matricule_t & matricule){ map_matricule_t::iterator fit = map_matricule.find(matricule); if (fit == map_matricule.end()) return false; // pas trouvé const nom_t & nom = fit->first; const prenom_t & prenom = fit->second; //... supprimer de map_nom (A compléter) //... supprimer de map_prenom (A compléter) // supprimer de map_matricule map_matricule.erase(fit); return true; }
Pour une modification il suffit de faire une suppression suivie d'un ajout. Dans la classe datas_etudiant_t :
void modifier_etudiant( const matricule_t & matricule, const nom_t & nouveau_nom, const prenom_t & nouveau_prenom ){ supprimer_etudiant(matricule); ajouter_etudiant(matricule,nouveau_nom,nouveau_prenom); }
En cas de soucis n'hésite pas à repasser.
Bonne chance
yannboensit2007
Messages postés
67
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
10 mai 2010
14 mai 2007 à 16:59
14 mai 2007 à 16:59
Merci mamiemando,je penses qu'il me faut encore beaucoup de lecture
mamiemando
Messages postés
33344
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
7 novembre 2024
7 803
15 mai 2007 à 11:03
15 mai 2007 à 11:03
Yep, je te conseille de regarder un tutoriel sur la STL. Ca vaut vraiment le coup de prendre un peu de temps pour voir comment ça marche car quand tu sais l'utiliser tu gagnes un temps fou, et les "seg fault" deviennent beaucoup moins fréquentes. En effet, tu n'as plus besoin de te poser de question en terme d'allocation mémoire, il se débrouille tout seul (cf code que je t'ai donné).
Quelques rappels de C++ (j'ai l'impression que tu as surtout fait du C jusqu'ici) :
- les classes sont des structures ou certains "membres" ne sont pas accessibles partout dans le programme (private, protected, public).
- à chaque structure et classe peut être rattaché des méthodes (c'est à dire une fonction qui s'applique à un objet de cette classe). Par exemple ajouter_etudiant et une méthode de data_etudiants_t
- en C++ tu as la notion de référence (const plop & p). Syntaxiquement tout se passe comme si tu manipulais directement un objet plop, mais algorithmiquement parlant tout se passe comme si tu manipulais un pointeur sur cet objet. Sauf que contrairement à un pointeur, une référence doit toujours être initialisée.
- tu peux accéder aux typedef publics d'une classe avec l'opérateur ::. Par exemple les types iterator et const_iterator sont des types définis dans chaque classe de la STL. L'opérateur :: sert aussi à accéder aux classes, fonctions, et structure d'un "namespace". Par exemple les classes de la STL sont toutes dans le namespace std, et c'est pourquoi on écrit par exemple std::set, std::map etc... Il faut voir un namespace comme une sorte de répertoire dans le code. Les namespaces servent essentiellement à éviter des conflits sur les noms de fonctions et à organiser le code.
- en C++ plutôt que d'utiliser des printf on utilise des streams (flux) sur lesquels ont lit/écrit avec les opérateurs << (l'équivalent du scanf) et >> (l'équivalent du printf). Les sorties et entrées standards stdin, stdout, stderr ont leurs homologue flux std::cin, std::cerr, std::cout.
Bon courage
Quelques rappels de C++ (j'ai l'impression que tu as surtout fait du C jusqu'ici) :
- les classes sont des structures ou certains "membres" ne sont pas accessibles partout dans le programme (private, protected, public).
- à chaque structure et classe peut être rattaché des méthodes (c'est à dire une fonction qui s'applique à un objet de cette classe). Par exemple ajouter_etudiant et une méthode de data_etudiants_t
- en C++ tu as la notion de référence (const plop & p). Syntaxiquement tout se passe comme si tu manipulais directement un objet plop, mais algorithmiquement parlant tout se passe comme si tu manipulais un pointeur sur cet objet. Sauf que contrairement à un pointeur, une référence doit toujours être initialisée.
- tu peux accéder aux typedef publics d'une classe avec l'opérateur ::. Par exemple les types iterator et const_iterator sont des types définis dans chaque classe de la STL. L'opérateur :: sert aussi à accéder aux classes, fonctions, et structure d'un "namespace". Par exemple les classes de la STL sont toutes dans le namespace std, et c'est pourquoi on écrit par exemple std::set, std::map etc... Il faut voir un namespace comme une sorte de répertoire dans le code. Les namespaces servent essentiellement à éviter des conflits sur les noms de fonctions et à organiser le code.
- en C++ plutôt que d'utiliser des printf on utilise des streams (flux) sur lesquels ont lit/écrit avec les opérateurs << (l'équivalent du scanf) et >> (l'équivalent du printf). Les sorties et entrées standards stdin, stdout, stderr ont leurs homologue flux std::cin, std::cerr, std::cout.
Bon courage
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
yannboensit2007
Messages postés
67
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
10 mai 2010
15 mai 2007 à 16:34
15 mai 2007 à 16:34
ok merci encore pour tous les conseils
11 mai 2007 à 19:59