|
|
|
|
Bonjour tout le monde! Je suis une débutante en programmation C++ et j'ai un exercice à faire qui est assez difficile pour moi. Voici l'énoncé de cela:
Concevoir un programme en C++ qui lit le fichier dinfo.txt , réalise un tri en ordre alphabétique sur le champ nom et sauvegarde le résultat dans un autre fichier appelé dinfo_apres_tri.txt . On suppose que le contenu du fichier dinfo.txt ne dépasse jamais 10 000 lignes.
En fait, le fichier dinfo.txt est une structure qui comporte une colonne de Nom, de Prénom, de Type, de Type d'appareil, de #extension téléphonique, de Bureau, de #prise, de #inventaire, d'adresse physique et d'adresse IP. Chaque colonne est séparée par un espace ou une tabulation, tous les champs sont remplis et ce fichier est sous format texte.
Voici ce que j'ai fait jusqu'à maintentant, mais je suis bloquée et je n'arrive pas à poursuivre... :
#include <iostream>
#include <fstream>
using std::cout;
using std::ifstream;
struct Info {
char Nom [30] ;
} ;
Lire_element (ifstream Fichier) {
Info Etudiant ;
Fichier >> Etudiant.Nom ;
Return Etudiant ;
}
main () {
ifstream Lecture ;
Info Membre ;
Lecture.open("dinfo.txt") ;
Membre = Lire_element (Lecture) ;
while ( ! Lecture.eof() ) {
for (i=0 ; i<strlen(Nom) ; i++) {
J'espère tellement que vous pourriez m'aider à me débloquer. Merci beaucoup!
Il manque la fin du programme. En fait c'est vraiment très simple à faire si tu utilises la structure map<> de la STL :
#include <fstream>
#include <iostream>
#include <string>
#include <map>
// Une structure contenant les infos
struct infos{
std::string nom;
std::string prenom;
std::string appareil;
std::string prise;
std::string inventaire;
std::string adresse_ip;
};
// Parser une ligne d'info
bool read_line_infos(
const std::string & f_in,
struct infos & data
){
//Lit une chaine et met infos dans data
//return true si tout va bien, false sinon
}
// Lire le fichier d'info et le mettre dans un dico
bool read_file_infos(
std::string & filename_in,
std::map<std::string,struct infos> & dico
){
std::ifstream f_in(filename_in);
if (f_in){
std::string ligne; // variable contenant chaque ligne lue
// cette boucle s'arrête dès qu'une erreur de lecture survient
for(unsigned int no_line=1;std::getline(fichier, ligne);++no_line){
// afficher la ligne à l'écran
struct infos data;
if( !read_line_infos(ligne,data) ){
std::cerr << "La ligne " << no_line
<< "["<< ligne << "]" << std::endl;
}else{
dico[data.nom]=data;
}
}
return true;
}
std::cerr << "Le fichier " << filename
<< "n'a pu être ouvert" << std::endl;
return false;
}
bool read_file_infos(
std::string & filename_out,
const std::map<std::string,struct infos> & dico
){
std::ofstream f_out(filename_out);
if(f_out){
std::map<std::string,struct infos>::const_iterator
dit(dico.begin()),
dend(dico.end());
for(;dit!=dend;++dit){
const struct_info & data=dit->second;
f_out << data.nom << "\t" << data.prenom << std::endl;
}
return true;
}
return false;
}
int main(){
const std::string filename_in="plop.txt";
const std::string filename_out="plop2.txt";
std::map<std::string,struct infos> dico;
// Lire le fichier
read_file_infos(filename_in,dico);
// Ecrire les datas
read_sorted_file_infos(filename_out,dico);
return 0;
}
Ou quelque chose dans l'idée ;-) Bonne chance |
Bonjour!
|
Alors je ne sais plus si c'est toi ou pas qui m'avais déjà fourni la réponse : on l'a pas vu à l'école donc non... MAIS :)
|
Bon, c'est la vie...Vous ne me comprenez peut-être pas pour ce qui est de l'école et je ne sais pas trop de quoi vous parlez si c'était moi ou pas... En tout cas, je vais essayer de travailler cet exercice un peu plus selon ma petite connaissance et je vais le poster ici bientôt, s'il y a des erreurs, et on verra qu'est-ce que ça donne! |
Ce que tu peux faire aussi pour ton exercice c'est implémenter un objet équivalent à une map... Mais bon c'est une perte de temps.
|
Bon...J'ai essayé de faire du mieux que je peux avec ce que je connais jusqu'à maintenant. Cependant, dans mon main(){ je veux que le tri se fait là, mais comment puis-je passer d'un nom à un autre afin de les comparer pour les placer en ordre alphabétique?...
|
Tu peux utiliser les fonctions strcmp et qsort par exemple. la fonction qsort prend en paramètre un pointeur sur une fonction définissant ta relation d'ordre.
|
J'suis allée voir ce que vous m'aviez donné sur le qsort. Mais il y a une chose que je ne comprends pas. C'est que dans mon fichier dinfo.txt, je ne peux pas savoir c'est quoi le nombre de Nom qu'il y a de-dans, donc comment pourrais-je comparer nom par nom si je ne sais pas quand ça termine?!
|
Utilise la fonction getline :
extern "C"{
#include <string.h>
}
int main(){
printf("strcmp=%d\n",strcmp("plop","tapir"));
return 0;
}
Mais bon objectivement tu crois pas que ce serait plus simple si tu utilisais des string et des map, comme tout le monde ;) Bonne chance |
C'est surement plus simple avec les map et les string... Mais j'aimerais vraiment faire avec les structures et les fichiers de la façon que je fais, parce que j'aimerais bien maîtriser les notions de base en premier et après je pourrais faire avec des notions un peu plus complexes. Cependant, je n'arrive même pas à faire correctement mon programme... Bon voici ce que j'ai fait jusqu'à date (j'ai essayé de comprendre la fonction getline que vous m'aviez donné, en fait, ce qui est en gras ne me semble pas vraiment exact), pourriez-vous me débogger svp :
|
tp3.cpp:52: error: `Ligne2' does not name a type
std::string Ligne2 ; tp3.cpp:54: error: `Un_utilisateur' undeclared (first use this function) Tu as déclarer une variable "Un_utilisateur" mais dans la fonction Lire_Element, donc elle n'est utilisable que dans cette fonction. La variable de type utilisateur que tu as déclaré dans la fonction Main est User, donc : while ( strcmp (User.Nom , Ligne1) < 0) Voila pour les erreurs de compilation en tout cas, Good luck Moi je dis ça...je dis rien ^^
|
Bon...J'ai corrigé ce que Kiruasam m'a dit de corriger...MAIS ça ne fonctionne toujours pas...
|
Une fonction doit toujours avoir un type de retour, que tu as oublié de précisé :
Utilisateur Lire_Element (ifstream Fichier) {
Utilisateur Un_utilisateur;
Fichier >> Un_utilisateur.Nom ;
...
Fichier >> Un_utilisateur.Adresse_Ip ;
return Un_utilisateur;
}
Si la fonction ne retourne rien, son type de retour est void void plop(){
printf("plop\n");
}
Ensuite les messages d'erreurs te disent qu'ils ne connaissent pas strcmp, et pour cause, cette fonction attend en paramètre deux char*, et tu lui passes un char* et un std::string. Il faut donc convertir tes strings avec les méthodes c_str(). Par ailleurs tu peux utiliser : - l'opérateur = si à gauche de l'opérateur c'est un std::string pour faire une recopie de chaîne, à la place du strcpy. - l'opérateur == si à gauche de l'opérateur c'est un std::string pour faire une comparaison de chaîne, à la place du strcmp.
if (Infos) {
std::string Ligne1;
std::string Ligne2;
std::getline (Infos , Ligne1) ;
while ( ! Infos.eof() ){
while ( strcmp (User.Nom , Ligne1.c_str()) < 0) {
Ligne2=Ligne1;
Ligne1=User.Nom;
}
Nouveau << Ligne1 << endl;
}
}
Je t'invite à prendre le temps de lire les docs : http://www.sgi.com/tech/stl/basic_string.html http://www.hmug.org/man/3/strcmp.php http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man3/strcpy.3.html Bonne chance |
Merci pour votre support! Je pense que le programme fonctionne bien car il n'y a plus d'erreurs lors de la compilation. J'ai aussi ajouté :
|
Bon j'ai essayé de créer un programme qui va lire mon nouveau fichier dinfo_apres_tri.txt pour vérifier si mon premier programme a bien fait son travail de triage. Il n'y a pas eu d'erreurs de compilation, cependant, quand je l'exécute, il ne fait absolument rien. Que puis-je faire pour corriger tout ça?
|