Problème avec le chargement des données d'un fichier [C++] - Programmation
Marsh Posté le 08-06-2001 à 12:53:02
le fread ne retourne pas le caractere lu mais le nombre d'elements correctement lus donc dans ton cas 1 (si tout va bien).
Marsh Posté le 08-06-2001 à 12:55:58
C'est une maniere de programmer assez sale, qui ne va t'amener que des problemes.
Si ton fichier est effectivement un fichier texte, il vaut mieux faire comme ca en C++ :
#include <fstream>
#include <string>
void main()
{
ifstream f("data.txt" );
if (f==NULL) return; // fichier non ouvert
int hp, mp;
string name;
while (!f.eof())
{
string s;
f >> s;
if (s == "NAME:" )
f >> name;
if (s == "HP:" )
f >> hp;
if (s == "MP:" )
f >> mp;
}
f.close();
cout << "NAME = " << name << " ; HP = " << hp << " ; MP = " << mp << endl;
}
Il faut utiliser les flux quand c'est possible, parce que ca rulez...
[edit]--Message édité par tgrx--[/edit]
Marsh Posté le 08-06-2001 à 19:42:20
Les string name; marche pas chez moi, le compilateur ne les reconnait pas, j'ai bien mis #include <string.h> pourtant. Que dois-je faire?
Marsh Posté le 08-06-2001 à 19:55:17
#include <string> et non pas #include <string.h>
Pareil pour iostream...
Et c'est quoi ton compilateur ?
Marsh Posté le 08-06-2001 à 20:01:49
Visual C++ 5. Voici les erreurs qu'il affiche lors de la compilation:
--------------------Configuration: Loading - Win32 Debug--------------------
Compiling...
main.cpp
D:\Mes Documents\Programmation\Loading\main.cpp(9) : error C2065: 'string' : undeclared identifier
D:\Mes Documents\Programmation\Loading\main.cpp(9) : error C2146: syntax error : missing ';' before identifier 'name'
D:\Mes Documents\Programmation\Loading\main.cpp(9) : error C2065: 'name' : undeclared identifier
D:\Mes Documents\Programmation\Loading\main.cpp(13) : error C2146: syntax error : missing ';' before identifier 's'
D:\Mes Documents\Programmation\Loading\main.cpp(13) : error C2065: 's' : undeclared identifier
D:\Mes Documents\Programmation\Loading\main.cpp(16) : error C2446: '==' : no conversion from 'char *' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
D:\Mes Documents\Programmation\Loading\main.cpp(18) : error C2446: '==' : no conversion from 'char *' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
D:\Mes Documents\Programmation\Loading\main.cpp(20) : error C2446: '==' : no conversion from 'char *' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
Error executing cl.exe.
Loading.exe - 8 error(s), 0 warning(s)
Marsh Posté le 08-06-2001 à 20:06:53
tgrx > un site sympa sur l'utilisation des flux à me recommander ? merci
Marsh Posté le 08-06-2001 à 20:09:25
youdontcare > non desole moi mes references c'est fstream.h, iostream.h, streambuf.h, et le livre de Stroustrup...
alload > j'ai pas visual c++ sous la main, normalement ca devrait fonctionner, vu que string fait partie de la standard library du c++...
CEUX QUI CONNAISSENT VC++, POURQUOI CA RECONNAIT PAS string ?
Marsh Posté le 08-06-2001 à 20:15:39
un #include <file> à l'air d'être traité comme un #include <file.h>
ceci dit, #include <string> et #include <string.h> marchent avec mon visual (version 6, aucun service pack derrière). string.h est dans vc98\\include
bon je vais mater d'un peu plus près les streams ... j'ai toujours géré mes fichiers 'à la pogne', je sens que je me fais chier pour rien
Marsh Posté le 08-06-2001 à 20:23:08
bon je raconte nimpe, il trouve le fichier mais n'arrive pas à compiler ton exemple. pourtant c'est kif kif la même chose que dans la doc ...
Marsh Posté le 08-06-2001 à 20:25:49
il faut faire
#include <string>
using namespace std;
feinte: string.h n'est pas la version de string sans namespace, mais en fait (pour des raisons de compatiblité), il s'agit des strings version C et non C++.
De plus, si tu fais
#include <string>
sans faire using namespaces std
il faudra par la suite faire:
std::string name;
...
car toutes les classes du standard C++ (ex-STL) sont dans le namespace std;
Les streams BIEN
Les char * PAS BIEN
La STL BIEN
Les pointeurs non protégés PAS BIEN
Les flux BIEN
fwrite PAS BIEN
le C PAS BIEN
le C++ BIEN
...
Marsh Posté le 08-06-2001 à 20:46:17
janoscoder > ok, merci. il manquait également un #include <iostream> pour cout, maintenant ça compile.
qu'appelles tu 'pointeurs non protégés ?'
Marsh Posté le 08-06-2001 à 21:00:35
Dernière version de mon code;
#include <fstream.h>
#include <string>
int main()
{
ifstream datafile ("data.txt" );
int hp, mp;
std::string name;
while (!datafile.eof())
{
std::string buffer;
datafile >> buffer;
if (buffer == "NAME:" )
{
datafile >> name;
}
if (buffer == "HP:" )
{
datafile >> hp;
}
if (buffer == "MP:" )
{
datafile >> mp;
}
}
datafile.close();
cout << name << endl;
cout << hp << endl;
cout << mp << endl;
while (1)
{
}
return 0;
}
Ca marche toujours pas. Voilà les erreurs:
D:\Mes Documents\Programmation\Loading\main.cpp(62) : error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no a
cceptable conversion)
D:\Mes Documents\Programmation\Loading\main.cpp(66) : error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no a
cceptable conversion)
D:\Mes Documents\Programmation\Loading\main.cpp(82) : error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no a
cceptable conversion)
Error executing cl.exe.
Où est le problème?
Encore un truc, comment marche les f>>s? Ca envoit quoi dans s? Une lettre ou plusieurs?
Marsh Posté le 08-06-2001 à 21:28:42
C'est marrant ca, je croyais que les operateurs << et >> etaient surcharges pour accepter les strings... en tout cas GCC 2.95.2 le fait tres bien.
Alload> pq tu veux pas faire un #include <fstream> au lieu de fstream.h ? Et puis le using namespace std n'engage a rien (vu le programme actuel), et rend le code plus lisible...
Marsh Posté le 08-06-2001 à 21:51:29
Y'a un truc qu'il faut savoir, et microsoft est très discret avec. Il y a deux version INCOMPATIBLES de la STL dans Visual. Celle avec les .h et celle sans. Les erreurs n'apparaissent pas forcément au début. Genre si on utilise les strings et les flux sans jamais vouloir mettre de strings dans les flux, tout va bien, sinon c'est la merde. Faut pas s'inquiéter et il faut choisir une version. Celle sans les .h est plus récente et et faite pour coller à la norme (ils on même enlevé qqes fonctionnalités pour que ça fonctionne). Le pire c'est que l'aide, ils ne précident pas toujours de quel version il s'agit, et don il faut aller voir en haut si ça a trait à un fichier .h ou pas .h.
D'ailleurs toute recherche dans la doc (relativement à la STL) donne systématiquement au moins deux réponses, une attachée à chaque version.
enfin, si on utilise la version sans .h, faut pas oublier de faire des using namespace std;
Marsh Posté le 08-06-2001 à 21:53:59
Ok donc la conclusion de tout ca c'est :
#include <fstream>
using namespace std;
Marsh Posté le 08-06-2001 à 22:35:43
Encore un truc, comme on est bien parti dans les fluxs.
Comment faire pour mettre une phrase prise au clavier dans un string?
J'ai fais ce code mais il s'arrete après un espace tappé donc ça va pas...
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ofstream savefile("save.txt" );
string buffer2;
cout << "\n\nEcrivez ce que vous voulez sauvegarder:" << endl;
cin >> buffer2;
savefile << buffer2;
savefile.close();
while (1)
{
}
return 0;
}
Marsh Posté le 08-06-2001 à 23:50:42
Tu fais un :
string line;
getline(cin, line, '\n')
Ca marche aussi pour les fichiers, il suffit de mettre un flux entrant en parametre (cin, un ifstream ou autre), et le dernier parametre est le caractere terminal, i.e. ce qui specifie la fin de la ligne
Marsh Posté le 09-06-2001 à 00:02:45
Si tu veux une version correcte de la STL avec le compilo C++ microsoft, une seule solution, acheter celle de dinkumware.
A+,
Marsh Posté le 09-06-2001 à 09:45:55
Juste une question, tout les trucs que vous m'apprenez ne sont pas dans mon bouquins de C++. Y aurait-il un endroit où apprendre tout ça directement?
Marsh Posté le 09-06-2001 à 09:54:15
tgrx a écrit a écrit : Tu fais un : string line; getline(cin, line, '\n') Ca marche aussi pour les fichiers, il suffit de mettre un flux entrant en parametre (cin, un ifstream ou autre), et le dernier parametre est le caractere terminal, i.e. ce qui specifie la fin de la ligne |
Ca marche, y a juste un petit problème, il faut tapper deux fois ENTER pour que la saisi prenne fin.
Marsh Posté le 09-06-2001 à 15:40:21
c'est bizarre... je viens de compiler le prog suivant avec gcc sous Linux :
#include <iostream>
#include <fstream>
void main()
{
string line;
getline(cin,line,'\n');
cout << line << endl;
}
Et ca fonctionne parfaitement, un seul appui sur 'return'.
[edit]--Message édité par tgrx--[/edit]
Marsh Posté le 09-06-2001 à 17:07:12
Je pige pas non plus... M'enfin bon, ça fait rien.
Merci quand même beaucoup!!!
Marsh Posté le 10-06-2001 à 00:00:21
->youdontcare,
ah oui, la question sur un pointeur non protégé:
Si tu alloues des données au sein d'une fonction par exemple, et que ces données ne serviront pas au dela de la fonction, mieux vaut utiliser un classe qui se comporte comme un pointeur, mais qui libérera la mémoire à sa destruction (cf auto_ptr dans le bouquin de Stroustrup)
La bonne façon de voir les choses est de se dire que chaque objet alloué dynamiquement et qui n'est pas détruit à la fin de la portée doit avoir un propriétaire, un conteneur, qui se charge de le détruire à sa mort.
Ca évite les fuites mémoire, pas exemple, et c'est plus facile de savoir combien d'objets ont été alloués, etc...en regardant l'état du conteneur. La STL fournit des conteneurs de base, mais en écrire d'autres ne pose pas de problème.
Marsh Posté le 08-06-2001 à 12:48:43
Voilà mon code:
#include <iostream.h>
#include <stdio.h>
int main()
{
FILE *datafile;
if ( (datafile = fopen ("data.txt", "r" )) == NULL )
{
cout << "Erreur dans le chargement du fichier." << endl;
while (1)
{
}
}
char buffer;
char read[256];
int x = 0;
while ( (fread (&buffer, sizeof (char), 1, datafile)) != ':' )
{
read[x] = buffer;
x++;
}
x = 0;
while ( read[x] != NULL )
{
cout << read[x];
x++;
}
cout << endl;
fclose (datafile);
while (1)
{
}
return 0;
}
Le fichier data.txt contient:
NAME: Alucard
HP: 50
MP: 30
Je voudrais pouvoir extraire le nom, le nombre de HP et de MP plus tard, pour le moment je voudrais juste que l'exe lise jusqu'au premier ":" puis traite le mot qu'il a lu. J'ai pas encore mis la code pour le traitement du mot, j'ai un problème car quand je lance l'exe la fenetre s'arrete tout de suite sans rien afficher.
D'où vient le problème?