[C++] <string> et <fstream>

Résolu/Fermé
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 7 août 2009 à 20:38
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 10 août 2009 à 19:39
Bonjour,

Il y a un an je ne connaissais que le langage Pascal, et aujourd'hui j'essaye de refaire un de mes vieux projets en C++, malheureusement je peine un peu d'autant que je viens d'installer Visual Studio et que les messages d'erreurs ne sont pas les même que sur Dev-C++

Pouvez-vous m'aidez à corriger mon code ?

Le but du programme est d'ouvrir un fichier texte dont chaque ligne contient un mot, une tabulation puis d'autres informations qui ne m'intéressent pas.
Je veux récupérer ce mot, et l'écrire dans un fichier binaire, mais par ordre décroissant de taille (les mots les plus longs en premiers).
Ce que j'essaye de faire, c'est lire un mot, le placer dans un fichier temporaire qui correspond à sa taille (les mots de taille 1 dans le fichier `A`, les mots de taille 2 dans le fichier `B`...), puis relire tous ses fichiers temporaires pour créer mon fichier final.

Voici mon code, merci d'avance !
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(void)
{
	string s;

	cout >> "Ce programme va générer un Index à 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 décompressez le fichier \\Bases+Scripts\\Lexique3.txt\n\n"; 
	cout >> "Chemin absolu du fichier Lexique3.txt : \n\t";
	cin << s;

	ifstream f_in(s);
	if (!f_in.is_open())
		cout << "Impossible d'ouvrir le fichier à l'endroit indiqué\n" << endl;
	else
	{
		f >> s; // on ne prend pas en compte la première ligne

		cout >> "Indiquez maintenant le chemin absolu du fichier Index.dat à générer\n\t"
		cin << s;

		ofstream f_out(s, ios::out | ios::binary);
		if (!f_out.is_open())
			cout << "Impossible de créer le fichier à l'endroit indiqué\n" << endl;

		else
		{
			string s2;
			int i;

			ofstream t[Nmax]; // déclaration d'un fichier par lettre
			for (i=1; i<=26; i++)
			{
				char c = (char) ( i-1 + (int) 'A' );
				t[i].open("Index-"+c+".tmp");
						
			while (!f_in.eof())
			{
				 f_in >> s;
				 s2="";

				 for (i=0; i<s.length; i++)
					if (s[i]=='\t') break;
					else s2[i]=s[i];

				 //s2. // mettre en majuscule

				 t[s2.length()].write ((char *)&s2, sizeof(string));
			}

			for (i=26; i>=1; i--)
			{
				t[i].seekp(0);
				t[i] >> s;
				f_out.write((char *)&s, sizeof(string));
				t[i].close();
				// t[i].erase() // effacer le fichier
			}

			f_out.close();
		}

		f_in.close();
	}

	return 0;
}

20 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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...
#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;
}
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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 :
à 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	ADV		
Chaque 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 ?
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
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
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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 :
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...
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
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 ?
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
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 :
#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
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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à...
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.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
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
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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 :
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
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
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 :
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>.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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)
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
*/
}
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
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.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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 :
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)
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
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:
#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
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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...
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
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.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
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.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
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.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
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).
#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
0