[C++] <string> et <fstream>
Résolu/Fermé
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
-
7 août 2009 à 20:38
mamiemando Messages postés 33650 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2025 - 10 août 2009 à 19:39
mamiemando Messages postés 33650 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2025 - 10 août 2009 à 19:39
20 réponses
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
9 août 2009 à 17:50
9 août 2009 à 17:50
J'ai corrigé mon code, lors de la génération je n'ai plus d'erreurs, cependant à l'exécution ça plante quand même...
Quelqu'un peut-il m'aider à trouver où mon code pose problème ? merci...
Quelqu'un peut-il m'aider à trouver où mon code pose problème ? merci...
#include <iostream> #include <fstream> #include <string> const int Nmax=26; // nombre de lettres maximum pouvant être utilisé pour un seul mot dans l'index using namespace std; int main(void) { // ouverture (et vérification d'ouverture) des fichiers d'entrée et de sortie char ch[100]; string s; cout << "Ce programme va generer un Index a partir de la base de mots `Lexique`\n"; cout << "Procurez vous d'abord le zip sur http://www.lexique.org/telLexique.php\n"; cout << "Puis decompressez le fichier \\Bases+Scripts\\Lexique3.txt\n\n"; cout << "Chemin absolu du fichier Lexique3.txt : \n\t"; cin >> ch; cout << "\n"; // ouverture en lecture du fichier texte ifstream f_in(ch); if (!f_in.is_open()) { cout << "Impossible d'ouvrir le fichier à l'endroit indiqué\n" << endl; } else { cout << "Indiquez maintenant le chemin absolu du fichier Index.dat a generer\n\t"; cin >> ch; // ouverture en écriture du fichier binaire ofstream f_out(ch, ios::out | ios::binary); if (!f_out.is_open()) { cout << "Impossible de créer le fichier à l'endroit indiqué\n" << endl; f_in.close(); } else // début du code s'il n'y a pas eu de problème avec les ouvertures de fichiers { string s_in,s_out; unsigned int i; f_in >> s_in; // on ne prend pas en compte la première ligne (la légende du fichier) char * temp="Index-00.tmp"; ofstream t_out[Nmax]; // ouverture en écriture d'un fichier texte par taille de mot possible for (i=0; i<Nmax; i++) { temp[6]=(char) ( (int) '0'+ (i+1)/10); temp[7]=(char) ( (int) '0'+ (i+1)%10); t_out[i].open(temp); } // Eclatement du fichier d'origine en fichiers temporaires while (!f_in.eof()) { f_in >> s_in; s_out=""; for (i=0; i<s_in.length() && s_in[i]!='\t'; i++) s_out[i]=s_in[i]; // s_out. // mettre en majuscule if (s_out.length()<=Nmax) t_out[s_out.length()-1].write ((char *)&s_out, sizeof(string)); } ifstream t_in[Nmax]; // regroupement des fichiers temporaires dans le fichier de sortie for (i=Nmax-1; i>=0; i--) { t_out[i].close(); temp[6]=(char) ( (int) '0'+ (i+1)/10); temp[7]=(char) ( (int) '0'+ (i+1)%10); t_in[i].open(temp); while (!t_in[i].eof()) { t_in[i] >> s_in; f_out.write((char *)&s_in, sizeof(string)); } t_in[i].close(); // t_in[i].erase() // effacer le fichier } f_out.close(); } // fin du code s'il n'y a pas eu de problèmes avec les ouvertures de fichiers } return 0; }
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
9 août 2009 à 20:39
9 août 2009 à 20:39
Bon j'espère attirer un peu plus de réponse en précisant ma question.
J'ai un fichier qui contient des milliers de lignes comme celle-ci :
Cependant seul le premier champ m'intéresse (ici : "à l'improviste") mais je n'arrive pas à l'extraire.
J'ai essayé avec <cstdio> fscanf(f_in,"%s",&s); et avec <fstream> f_in >> s;
Mais avec aucun des deux je n'arrive à obtenir le résultat voulu.
Comment pourrais-je m'en sortir ?
J'ai un fichier qui contient des milliers de lignes comme celle-ci :
à l'improviste al5pROvist à l'improviste ADV 2.67 4.53 2.67 4.53 1 1 1 14 10 V C'VCCCVCVCCV VCVCCVCVCC 0 0 6 4 a-l5-pRO-vist 4 V-CV-CCV-CVCC etsivorpmi'l à tsivORp5la à l'im-pro-vis-te ADVChaque ligne est séparé par un "\n" et contient 31 champs séparés par une tabulation "\t"
Cependant seul le premier champ m'intéresse (ici : "à l'improviste") mais je n'arrive pas à l'extraire.
J'ai essayé avec <cstdio> fscanf(f_in,"%s",&s); et avec <fstream> f_in >> s;
Mais avec aucun des deux je n'arrive à obtenir le résultat voulu.
Comment pourrais-je m'en sortir ?
mamiemando
Messages postés
33650
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2025
7 846
10 août 2009 à 01:18
10 août 2009 à 01:18
Tu peux utiliser la lib pcre mais c'est un peu surdimensionné, un simple std::getline et un sscanf suffisent à extraire la valeur qui t'intéresse.
Est-ce que tu peux nous préciser le format de ton fichier ?
Bonne chance
Est-ce que tu peux nous préciser le format de ton fichier ?
Bonne chance
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
10 août 2009 à 01:26
10 août 2009 à 01:26
Effectivement en cherchant un peu partout je suis finalement tombé sur getline que je ne connaissais pas.
J'arrive ainsi à faire getline(f_in,s_io,'\t'); getline(f_in,s_trash,'\n'); pour récupérer la seule information qui m'intéresse sur chaque ligne.
Du moins en théorie car je n'ai pas encore réussi à débugger suffisamment en amont pour voir si ça marchait.
Je ne sais pas trop ce que tu entends par "format" du fichier, c'est un fichier .txt de 21,5 Mo contenant 31 champs par ligne séparés chacun par une tabulation.
J'arrive ainsi à faire getline(f_in,s_io,'\t'); getline(f_in,s_trash,'\n'); pour récupérer la seule information qui m'intéresse sur chaque ligne.
Du moins en théorie car je n'ai pas encore réussi à débugger suffisamment en amont pour voir si ça marchait.
Je ne sais pas trop ce que tu entends par "format" du fichier, c'est un fichier .txt de 21,5 Mo contenant 31 champs par ligne séparés chacun par une tabulation.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
10 août 2009 à 01:46
10 août 2009 à 01:46
Dans mon débugage je ne comprends pas cette erreur "Exception non gérée à 0x5fda7918 (msvcp90d.dll) dans Index.exe : 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00000004."
L'erreur apparaît dans le "if" à la fin de cette partie de mon code :
L'erreur apparaît dans le "if" à la fin de cette partie de mon code :
unsigned int i=0; string s_io; // pour transiter les informations entre les fichiers string s_trash; // pour récupérer les données inutiles string s_tmp; // pour désigner les fichiers temporaires fstream f_tmp[Nmax]; char ch[3]="00"; for (i=0; i<Nmax; i++) { _itoa_s(i+1,ch,2*sizeof(int),10); s_tmp = ch_tmp + string(ch) + ".tmp"; f_tmp[i].open(s_tmp.c_str(), ios::in | ios::out | ios::trunc); } // Eclatement du fichier d'origine dans les fichiers temporaires getline(f_in,s_trash,'\n'); // on ne prend pas en compte la première ligne while (!f_in.eof()) { getline(f_in,s_io,'\t'); getline(f_in,s_trash,'\n'); if (s_io.length()<=Nmax) f_tmp[i] << s_io << "\n"; }Ça doit pas être grand chose mais je débute avec les fichiers et les strings en C++ et visiblement là il y a un truc que je vois pas...
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
10 août 2009 à 09:17
10 août 2009 à 09:17
if (s_io.length()<=Nmax) f_tmp[i] << s_io << "\n";
Question qui devrait t'aider à résoudre : que vaut i ?
Pourquoi avoir Nmax fichiers pour écrire alors qu'un seul semble te suffire ?
mamiemando
Messages postés
33650
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2025
7 846
10 août 2009 à 10:31
10 août 2009 à 10:31
Je ne sais pas trop ce que tu entends par "format" du fichier, c'est un fichier .txt de 21,5 Mo contenant 31 champs par ligne séparés chacun par une tabulation.
Par exemple dans ton fichier, la première colonne est toujours un float, la seconde est toujours une chaîne etc... et chaque colonne est séparée par une tabulation.
Violation d'accès lors de la lecture de l'emplacement 0x00000004.
C'est une erreur de segmentation, ça veut dire que tu tentes d'écrire dans une zone mémoire qui n'est pas allouée par ton programme.
En fait il y a plusieurs choses que je ne comprends pas dans ton code, notamment
- pourquoi tu ouvres Nmax fichiers,
- quand est ouvert f_in,
- quand est-ce que tu fermes les fichiers ouverts avec succès,
- ...
Au niveau des getlines, splitte simplement sur \n et stocke le résultat dans une std::string. Il suffit ensuite d'utiliser strtok ou ou sscanf sur la chaîne retournée par la méthode c_str().
Pour ouvrir un fichier pas besoin de tous les flags, par contre il faut vérifier qu'il s'est ouvert avec succès avant d'enchaîner :
Bonne chance
Par exemple dans ton fichier, la première colonne est toujours un float, la seconde est toujours une chaîne etc... et chaque colonne est séparée par une tabulation.
Violation d'accès lors de la lecture de l'emplacement 0x00000004.
C'est une erreur de segmentation, ça veut dire que tu tentes d'écrire dans une zone mémoire qui n'est pas allouée par ton programme.
En fait il y a plusieurs choses que je ne comprends pas dans ton code, notamment
- pourquoi tu ouvres Nmax fichiers,
- quand est ouvert f_in,
- quand est-ce que tu fermes les fichiers ouverts avec succès,
- ...
Au niveau des getlines, splitte simplement sur \n et stocke le résultat dans une std::string. Il suffit ensuite d'utiliser strtok ou ou sscanf sur la chaîne retournée par la méthode c_str().
Pour ouvrir un fichier pas besoin de tous les flags, par contre il faut vérifier qu'il s'est ouvert avec succès avant d'enchaîner :
#include <fstream> #include <cstdio> int main(){ std::string line; std::ifstream ifs("pouet.txt"); if(!ifs){ std::cerr << "ouverture impossible" << std::endl; return 1; } while(std::getline(ifs,line)){ std::cout << line << std::endl; const char *s = line; // sscanf ou strtok } ifs.close(); return 0; }
Bonne chance
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
10 août 2009 à 10:31
10 août 2009 à 10:31
Merci Char Snipeur (et mamiemando que j'ai oublié de remercier hier) effectivement le i n'a rien à faire là...
Mon fichier d'origine "f_in" qui contient des informations sur des mots triés dans l'ordre lexicographique.
Mon fichier de sortie "f_out" (binaire de préférence) qui devra contenir uniquement l'orthographe de ces mots mais triés par ordre de taille (du plus grand au plus petit) tout en conservant l'ordre lexicographique (c'est pour être utilisé après pour les recherche d'anagrammes)
C'est pour ça que j'utilise Nmax fichiers temporaires (24 en fait) pour lire une seule fois le fichier f_in, mettre les mots de taille n dans le fichier n.tmp, puis les relire du fichier 24 au fichier 1 pour les mettre dans f_out.
if (s_io.length()<=Nmax) f_tmp[s_io.length()] << s_io << "\n";En fait j'utilise Nmax+2 fichiers :
Mon fichier d'origine "f_in" qui contient des informations sur des mots triés dans l'ordre lexicographique.
Mon fichier de sortie "f_out" (binaire de préférence) qui devra contenir uniquement l'orthographe de ces mots mais triés par ordre de taille (du plus grand au plus petit) tout en conservant l'ordre lexicographique (c'est pour être utilisé après pour les recherche d'anagrammes)
C'est pour ça que j'utilise Nmax fichiers temporaires (24 en fait) pour lire une seule fois le fichier f_in, mettre les mots de taille n dans le fichier n.tmp, puis les relire du fichier 24 au fichier 1 pour les mettre dans f_out.
mamiemando
Messages postés
33650
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2025
7 846
10 août 2009 à 10:36
10 août 2009 à 10:36
Mon fichier de sortie "f_out" (binaire de préférence) qui devra contenir uniquement l'orthographe de ces mots mais triés par ordre de taille (du plus grand au plus petit) tout en conservant l'ordre lexicographique (c'est pour être utilisé après pour les recherche d'anagrammes)
Si j'ai bien suivi tu tries :
1) sur la longueur
2) sur l'ordre alphabétique
Si c'est ça, pas de problème. Sinon je n'ai pas compris.
C'est pour ça que j'utilise Nmax fichiers temporaires (24 en fait)
Pourquoi 24 fichiers ? Je ne vois pas ce que tu cherches à faire. Tu m'aurais dit 26 comme le nombre de lettres dans l'alphabet je dis pas, mais 24 ? Et pourquoi passer par des fichiers intermédiaires (écrire et lire un fichier c'est ce qu'il y a de plus lent, alors que tu as des containers assez fantastiques comme std::set et std::map).
https://forums.commentcamarche.net/forum/affich-37604421-introduction-a-la-stl-en-c-standard-template-library
Bonne chance
Si j'ai bien suivi tu tries :
1) sur la longueur
2) sur l'ordre alphabétique
Si c'est ça, pas de problème. Sinon je n'ai pas compris.
C'est pour ça que j'utilise Nmax fichiers temporaires (24 en fait)
Pourquoi 24 fichiers ? Je ne vois pas ce que tu cherches à faire. Tu m'aurais dit 26 comme le nombre de lettres dans l'alphabet je dis pas, mais 24 ? Et pourquoi passer par des fichiers intermédiaires (écrire et lire un fichier c'est ce qu'il y a de plus lent, alors que tu as des containers assez fantastiques comme std::set et std::map).
https://forums.commentcamarche.net/forum/affich-37604421-introduction-a-la-stl-en-c-standard-template-library
Bonne chance
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
10 août 2009 à 10:57
10 août 2009 à 10:57
En fait je me suis trompé c'est 25, parce que le mot le plus long "anticonstitutionnellement" a 25 lettres.
Par contre le fichier je ne le trie pas par ordre alphabétique, il y est déjà (je l'ai trouvé tel quel sur internet), je me contente de ne pas perdre cet ordre lorsque je trie par taille.
Si j'utilise des fichiers temporaires c'est parce que la taille de mon fichier est relativement grande (21,5 Mo) et que surtout je ne connais pas du tout les containers (à part les listes chainées et les piles).
Sinon je pourrai faire 25 allers-retours dans le fichiers f_in pour mettre d'abord les mots de taille 25, puis 24... dans f_out, mais ça me paraît être une méthode encore pire !
En ce qui concerne le format de mon fichier c'est :
Par contre le fichier je ne le trie pas par ordre alphabétique, il y est déjà (je l'ai trouvé tel quel sur internet), je me contente de ne pas perdre cet ordre lorsque je trie par taille.
Si j'utilise des fichiers temporaires c'est parce que la taille de mon fichier est relativement grande (21,5 Mo) et que surtout je ne connais pas du tout les containers (à part les listes chainées et les piles).
Sinon je pourrai faire 25 allers-retours dans le fichiers f_in pour mettre d'abord les mots de taille 25, puis 24... dans f_out, mais ça me paraît être une méthode encore pire !
En ce qui concerne le format de mon fichier c'est :
1_ortho : string 2_phon : string 3_lemme : string 4_cgram : string 5_genre : char 6_nombre : char 7_freqlemfilms2 : float 8_freqlemlivres : float 9_freqfilms2 : float 10_freqlivres : float 11_infover : string 12_nbhomogr : int 13_nbhomoph : int 14_islem : int 15_nblettres : int 16_nbphons : int 17_cvcv : string 18_p_cvcv :string 19_voisorth : int 20_voisphon : int 21_puorth : int 22_puphon : int 23_syll : string 24_nbsyll : int 25_cv-cv : string 26_orthrenv : string 27_phonrenv : string 28_orthosyll : string 29_cgramortho : string 30_deflem : int 31_defobs : int
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
10 août 2009 à 11:54
10 août 2009 à 11:54
Je pense que ton idée est pas mal, maintenant qu'elle est bien expliqué :)
le fichier s_tmpXX.tmp contient tout les mots de longueur XX triés par ordre alphabétique.
Par contre, tu définis f_tmp[Nmax];
C'est à dire que tes fichiers vont de f_tmp[0] à f_tmp[Nmax-1];
Or lorsque tu fais :
Ensuite, comme le dit mamiemando, ce n'est peux être pas la peine de se prendre la tête avec des fichiers temporaire. Et 21 Mo ce n'est pas énorme pour les PC actuel.
à ta place, je pense que j'utiliserai <sstream>.
le fichier s_tmpXX.tmp contient tout les mots de longueur XX triés par ordre alphabétique.
Par contre, tu définis f_tmp[Nmax];
C'est à dire que tes fichiers vont de f_tmp[0] à f_tmp[Nmax-1];
Or lorsque tu fais :
if (s_io.length()<=Nmax) f_tmp[s_io.length()] << s_io << "\n";si s_io.length()==Nmax tu risque fort une erreur de segmentation (et même si ce n'est pas le cas, ce n'est pas propre).
Ensuite, comme le dit mamiemando, ce n'est peux être pas la peine de se prendre la tête avec des fichiers temporaire. Et 21 Mo ce n'est pas énorme pour les PC actuel.
à ta place, je pense que j'utiliserai <sstream>.
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
10 août 2009 à 12:12
10 août 2009 à 12:12
Merci, en fait j'avais vu le problème du -1, car j'avais un décalage dans mes fichiers (les mots à 1 lettre dans le fichier 2 par exemple) et désolé de n'avoir pas été clair plus tôt pourtant j'avais essayé...
Maintenant j'arrive à avoir tous mes fichiers temporaires avec le contenu correct dedans avec <fstream>, qu'est-ce que ça changera d'utiliser <sstream> ?
Question subsidiaire, avec mes déclarations suivantes (pour rappel)
Maintenant j'arrive à avoir tous mes fichiers temporaires avec le contenu correct dedans avec <fstream>, qu'est-ce que ça changera d'utiliser <sstream> ?
Question subsidiaire, avec mes déclarations suivantes (pour rappel)
ofstream f_out(ch_out.c_str(), ios::out | ios::binary); fstream f_tmp[Nmax]; f_tmp[i].open(s_tmp.c_str(), ios::in | ios::out | ios::trunc);J'ai un problème avec ce morceau de code censé recomposer mes fichiers temporaires en un seul fichier
for (i=Nmax-1; i>=0; i--) { //* f_tmp[i].clear(); // retourne au début du fichier while (!f_tmp[i].eof()) { getline(f_tmp[i],s_io,'\n'); // lit une ligne contenant un mot f_out.write((char *)&s_io, sizeof(string)); // écrit en binaire le mot } //* f_tmp[i].close(); // ferme le fichier temporaire /* _itoa_s(i+1,ch,2*sizeof(int),10); s_tmp = ch_tmp + string(ch) + ".tmp"; remove(s_tmp.c_str()); // supprime le fichier temporaire */ }
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
10 août 2009 à 12:59
10 août 2009 à 12:59
Je ne crois pas que clear serve à ça. J'utiliserai plutôt seekp ou seekg.
L'interet de sstream serai de ne pas écrire dans un fichier, mais dans la RAM (dans une string) et donc d'aller un peu plus vite. Ensuite, il n'y aurai alors pas de problème de se remettre au début.
Un truc moche aussi :
f_out.write((char *)&s_io, sizeof(string));
string est une classe, il aut donc faire attention à ce que tu fais. sizeof(std::string) donne la taille de la classe, pas celle de la chaine. De même, es tu sur de ton cast (char*)&s_io ? la méthode pour avoir un char* à partir d'un string c'est d'utiliser la méthode string::c_str();
Enfin, je pense que le format binaire n'apporte rien. Il peut être intéressant lorsque tu traites des nombres (entiers ou flottant) mais pas lorsque tu traites des chaînes de caractère.
un caractère de type char prend un octet en ASCII comme en binaire.
L'interet de sstream serai de ne pas écrire dans un fichier, mais dans la RAM (dans une string) et donc d'aller un peu plus vite. Ensuite, il n'y aurai alors pas de problème de se remettre au début.
Un truc moche aussi :
f_out.write((char *)&s_io, sizeof(string));
string est une classe, il aut donc faire attention à ce que tu fais. sizeof(std::string) donne la taille de la classe, pas celle de la chaine. De même, es tu sur de ton cast (char*)&s_io ? la méthode pour avoir un char* à partir d'un string c'est d'utiliser la méthode string::c_str();
Enfin, je pense que le format binaire n'apporte rien. Il peut être intéressant lorsque tu traites des nombres (entiers ou flottant) mais pas lorsque tu traites des chaînes de caractère.
un caractère de type char prend un octet en ASCII comme en binaire.
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
10 août 2009 à 13:19
10 août 2009 à 13:19
Comme l'indique le titre de cette conversation, je ne suis sûr de rien en ce qui concerne les classes <string> et <fstream> que je ne connaissais pas du tout et qui sont mes principales sources d'erreurs dans ce progamme.
Je vais donc essayer de corriger mon code en mettant f_out en fichier texte (je ne passerai à <sstream> qu'une fois que je serai sûr que le reste du code est bon, ça me semble plus prudent)
Si j'ai bien compris la différence entre seekg et seekp c'est que l'un est pour les fichiers ouvert en lecture et l'autre pour ceux ouverts en écriture mais lequel utiliser pour mes fichiers temporaires qui sont ouvert à la fois en lecture et en écriture ?
Et la syntaxe pour les utiliser c'est quoi parce que Visual Studio me propose deux prototypes pour chaque mais je n'arrive pas à comprendre ce que je dois mettre dedans :
Je vais donc essayer de corriger mon code en mettant f_out en fichier texte (je ne passerai à <sstream> qu'une fois que je serai sûr que le reste du code est bon, ça me semble plus prudent)
Si j'ai bien compris la différence entre seekg et seekp c'est que l'un est pour les fichiers ouvert en lecture et l'autre pour ceux ouverts en écriture mais lequel utiliser pour mes fichiers temporaires qui sont ouvert à la fois en lecture et en écriture ?
Et la syntaxe pour les utiliser c'est quoi parce que Visual Studio me propose deux prototypes pour chaque mais je n'arrive pas à comprendre ce que je dois mettre dedans :
basic_istream<_Elem,_Traits>::_Myt & seekg (basic_istream<_Elem,_Traits>::pos_type_Pos) basic_istream<_Elem,_Traits>::_Myt & seekg (basic_istream<_Elem,_Traits>::off_type_Off, std::ios_base::seekdir_Way) basic_istream<_Elem,_Traits>::_Myt & seekp (basic_istream<_Elem,_Traits>::pos_type_Pos) basic_istream<_Elem,_Traits>::_Myt & seekp (basic_istream<_Elem,_Traits>::off_type_Off, std::ios_base::seekdir_Way)
mamiemando
Messages postés
33650
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2025
7 846
10 août 2009 à 13:34
10 août 2009 à 13:34
Très honnêtement je pense que tu te compliques vraiment la tâche à passer par des fichiers temporaires. A l'heure ou les PC ont plusieurs Go de RAM, sérieusement qu'est ce que 25Mo ?
Ton exercice se résout particulièrement simplement avec une std::map bien choisie et un std::set ou même un std::vector et un std::set. Je t'invite vivement à jeter un oeil au lien que je t'ai donn, il s'adresse justement aux personnes qui comme toi, ne connaissent pas encore les containers fournis par la STL.
Par exemple pour ton problème, voici ce que tu peux faire:
Bonne chance
Ton exercice se résout particulièrement simplement avec une std::map bien choisie et un std::set ou même un std::vector et un std::set. Je t'invite vivement à jeter un oeil au lien que je t'ai donn, il s'adresse justement aux personnes qui comme toi, ne connaissent pas encore les containers fournis par la STL.
Par exemple pour ton problème, voici ce que tu peux faire:
#include <map> #include <set> #include <string> #include <iostream> typedef std::map<unsigned,std::set<std::string> > datas_t; int main(){ datas_t datas; // On insère chaque mot lu dans ton fichier dans la structure datas // Ici par exemple j'insère le mot "tapir" std::string mot = "tapir"; datas[mot.length()].insert(mot); // et ainsi de suite pour chaque mot // On parcourt la structure datas datas_t::const_iterator datas_it (datas.begin()), datas_end(datas.end()); for(;datas_it != datas_end; ++datas_it){ const unsigned & length = datas_it->first; const std::set<std::string> & mots = datas_it->second; // On parcourt l'ensemble des mots de 'length' lettres std::set<std::string>::const_iterator mots_it (mots.begin()), mots_end(mots.end()); for(;mots_it != mots_end; ++mots_it){ std::cout << length << '\t' << *mots_it << std::endl; } } return 0; }
Bonne chance
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
10 août 2009 à 13:56
10 août 2009 à 13:56
Merci, je vais essayer de tirer profit de ton code, cependant j'avais déjà regardé ton lien et la complexité me posait problème car elle semble moins intéressante que celle que j'utilise (même si je comprends bien que mon code de débutant puisse être tout moche).
En effet si j'ai bien compris l'insertion dans une map est en log(n) auquel se rajoute l'insertion dans le set (en log(n) également) et ce n fois, soit n.log²(n), alors que moi je faisais sauf erreur du log(n)
Cependant j'apprends de mes erreurs et j'apprécie, je vais essayer de décortiquer tout ça...
Autre question, existe-t-il un moyen de mettre tous mes noms en majuscule ?
J'ai pas trouvé dans <string> et ios::uppercase n'a pas l'air de faire ce que j'en voulais...
En effet si j'ai bien compris l'insertion dans une map est en log(n) auquel se rajoute l'insertion dans le set (en log(n) également) et ce n fois, soit n.log²(n), alors que moi je faisais sauf erreur du log(n)
Cependant j'apprends de mes erreurs et j'apprécie, je vais essayer de décortiquer tout ça...
Autre question, existe-t-il un moyen de mettre tous mes noms en majuscule ?
J'ai pas trouvé dans <string> et ios::uppercase n'a pas l'air de faire ce que j'en voulais...
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
10 août 2009 à 14:04
10 août 2009 à 14:04
Tu as raison : vas y petit à petit. Mamiemando, tu as surement raison (moi, les map et set j'ai du mal...) mais dans une approche d'apprentissage, ça peut être formateur de terminer comme il a commencer et d'ensuite passer à quelque chose de plus C++.
C'est sur que Visual ne t'aide pas beacuoup. Pour tout ce qui concerne la STL, moi je regarde directement sur ce site :
https://en.cppreference.com/w/cpp/io/basic_istream/seekg
mais ça aide pour les détails, si tu débute avec, il vaut mieux faire autre chose. (les liens de mamiemando peut être).
pour le seek, je prendrai celui de l'input car c'est en lecture que tu vas utiliser le fichier. Mais je n'en sais rien.
C'est sur que Visual ne t'aide pas beacuoup. Pour tout ce qui concerne la STL, moi je regarde directement sur ce site :
https://en.cppreference.com/w/cpp/io/basic_istream/seekg
mais ça aide pour les détails, si tu débute avec, il vaut mieux faire autre chose. (les liens de mamiemando peut être).
pour le seek, je prendrai celui de l'input car c'est en lecture que tu vas utiliser le fichier. Mais je n'en sais rien.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
10 août 2009 à 14:10
10 août 2009 à 14:10
pour la casse, je n'ai rien trouver de standard, il faut faire ta propre fonction.
https://notfaq.wordpress.com/2007/08/04/cc-convert-string-to-upperlower-case/
Est assez élégant.
https://notfaq.wordpress.com/2007/08/04/cc-convert-string-to-upperlower-case/
Est assez élégant.
KX
Messages postés
16760
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
10 août 2009 à 15:09
10 août 2009 à 15:09
Merci à vous deux, j'ai finalement réussi à générer mon fichier.
Maintenant je vais regarder chacune de vos deux méthodes (la classe <sstream> et les conteneurs) pour voir comment ça marche, et les profits que je peux en tirer.
Maintenant je vais regarder chacune de vos deux méthodes (la classe <sstream> et les conteneurs) pour voir comment ça marche, et les profits que je peux en tirer.
mamiemando
Messages postés
33650
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2025
7 846
10 août 2009 à 19:39
10 août 2009 à 19:39
Pour les conteneurs la complexité est en O(log(m)*log(n)) ou m est le nombre de tailles de mots et n le nombre maximum de mots pour une taille donnée. De toute façon ce sera toujours plus rapide que de faire une étape par un fichier.
Si les mots ne sont pas dans ton index dans l'ordre alphabétique (pour une taille donnée) tu ne pourras pas avoir une meilleure complexité car tôt ou tard tu devras ordonner tes mots. Si dans le fichier d'entrée les mots sont dans le bon ordre (pour chacune des tailles) une liste est plus adaptée (O(log(m)).
Pour écrire les mots en majuscule tu peux utiliser la fonction toupper (inclue ctype).
Bonne chance
Si les mots ne sont pas dans ton index dans l'ordre alphabétique (pour une taille donnée) tu ne pourras pas avoir une meilleure complexité car tôt ou tard tu devras ordonner tes mots. Si dans le fichier d'entrée les mots sont dans le bon ordre (pour chacune des tailles) une liste est plus adaptée (O(log(m)).
Pour écrire les mots en majuscule tu peux utiliser la fonction toupper (inclue ctype).
#include <string> #include <iostream> #include <ctype> int main(){ std::string s = "taPir",sup; std::cout << s.length() << std::endl; for(std::size_t i=0;i<s.length();++i){ sup += toupper(s[i]); } std::cout << sup << std::endl; return 0; }
Bonne chance