Lecture d'un fichier en mode binaire - C++ - Programmation
Marsh Posté le 17-04-2005 à 22:47:54
# int entier;
# char fichier[20];
# cout << "saisir le nom du fichier a ouvrir (max 20 car): ";
# cin >> fichier; //saisie du chemin / nom
ignoble. vire tes char* et utilise std::string
#if(ficIn.is_open() == 0)
beurk
# hile(!ficIn.eof()) { //tant qu'on est pas a la fin du descripteur
# ficIn >> entier; //on recupere les entiers avec l'opérateur >>
perdu ... c'est là ton BUG A CAUSE D'UNE UTILISATION POURRIE DE EOF. HONTE A TOI ET A TOUS LES ENSEIGNANTS QUI PROPAGENT ENCORE ET TOUJOURS CE BUG !
while(ficIn >> entier) { ... }
# cout.flush(); //flush de cout
# ficIn.close(); //fermeture de ficIn
inutile
Marsh Posté le 17-04-2005 à 22:51:58
merci pour ta réponse diligente.
en fait je ne m'y connais pas trop en C++, a la base je connais mieux le C (enfin mieux...).
je vais voir ce que ca donne avec std::string
sinon ca marche ce que tu m'as dit!
je trouvais ca plutot logique neanmoins le eof, pq j'ai faux ? :x
mon prof c'est une moule j'en conviens...
dernieres questions car tu as l'air de plutot bien t'y connaitre:
j'aimerai acceder directement a un endroit du fichier et le parcourir sequentiellement c'est plutot stupide.
j'ai un souvenir de fseek mais la doc pourrie de vc++ ne m'avance pas tellement. et la j'ai pas nux pour developper correctement
exemple: acceder au nième int du fichier ...
da last question:
je voudrai ecrire ce pt1 de fichier en binaire, je fais donc ca:
ficOut.open(chemin, ios::out | ios::binary | ios::trunc)
ca me prend la tete car je peux le lire directement avec un viewer
Marsh Posté le 17-04-2005 à 22:57:47
que ce soit le feof du C ou eof du C++ c'est la même chose. Documente toi. eof qualifie une erreur d'E/S et ne la détecte pas. Je l'ai dit maintes fois sur ce forum (recherche).
Pourquoi avec ton utilisation la deuxième ligne se répète 2 fois ? parce que lors de la lecture de la dernière ligne, aucune erreur ne s'est produite. Donc eof() est faux. La prochaine tentative de lecture échoue, il y a erreur. À ce moment là, eof caractérise l'erreur comme fin de fichier.
une règle simple : n'utilise JAMAIS eof.
une écriture complète serait :
while(in >> entier) { ... }
if(in.eof()) { fin de fichier, ça va }
else { marne, il s'agit vraiment d'une erreur }
Marsh Posté le 17-04-2005 à 23:01:29
pour seek : impossible. Un fichier est une simple suite de caractères.
si tu dois faire des accès aléatoires, le mieux est sans doute de tout charger dans un std::vector
Code :
|
voire
Code :
|
Marsh Posté le 17-04-2005 à 23:04:26
mouais, je vois. je pensais qu'il existait une méthode pour accéder aléatoirement a un fichier, quoi que tu dois pouvoir te la faire toi meme apres quand tu connais la taille de chaque bloc non ?
enfin bon, non d'apres ce que tu me dis
Marsh Posté le 17-04-2005 à 23:08:37
si chaque enregistrement est à taille fixe, typiquement dans un fichier binaire, oui c'est possible. D'ailleurs j'y pense, ton code, c'est pour lire des entiers dans un fichier texte. Si tu ne dois stocker que des entiers, sans portabilité, en mode binaire, tu peux accèder directement à chaque entier directement.
Alors tu veux quoi : un fichier texte ou un fichier binaire ?
Marsh Posté le 17-04-2005 à 23:17:23
et j'ai un doute quant a mon utilisation de open, je fais ca:
out.open(nom, ios :: out | ios::binary | ios::trunc)
si je ne mets pas de \n le fichier est parfaitement lisible sous windows directement
Marsh Posté le 17-04-2005 à 23:19:10
1) n'utilise pas open, utilise le constructeur
2) si tu mets des '\n', alors c'est que tu structures ton fichier en ligne, donc c'est du texte.
Marsh Posté le 17-04-2005 à 23:21:12
argl, je comprends pas tellement ta réponse (oui je suis mauvais ).
la ligne que j'ai mise est dans le constructeur de MA classe.
faudrait ptet que je stock tous mes entiers dans un tableau puis que je les ecrive en bloque apres, du coup je pourrai ecrire en binaire?
Marsh Posté le 17-04-2005 à 23:25:17
bon, on reprends depuis le début : ton fichier tu veux qu'il soit lisible avec notepad ou pas ?
Marsh Posté le 17-04-2005 à 23:29:22
alors ni '\n' ni >>. Pas la peine de tout stocker dans un tableau (sauf raison d'efficacité)
Code :
|
ne fais ni trunc, ni rien. juste un ifstream("...", ios::binary) et c'est tout.
Marsh Posté le 17-04-2005 à 23:34:10
ah ok... je vais reprendre tout ce que j'ai fait.
et du coup pour ecrire je fais idem mais avec write.
je te remercie pour m'avoir éclairé
bonne soirée a toi !
Marsh Posté le 17-04-2005 à 23:40:57
istream.read / ostream.write
istream.seekg / istream.tellg
ostream.seekp / ostream.tellp
Marsh Posté le 17-04-2005 à 22:40:38
Bijour,
je suis pas un grand sachem en prog et je ne vois pas trop commment faire pour resoudre le probleme suivant:
le principe est d'ecrire une suite d'entier en binaire dans un fichier (a chaque entier ajouté, je rajoute un \n je voulais pas me prendre la tete avec une structure plus elaborée).
il faut aussi arriver a lire ces entiers...
mon probleme vient lors de la lecture, en fait quand je lis sequentiellement les données, la derniere ligne du fichier est répétée 2 fois. Je ne sais pas comment eliminer ce probleme.
J'ai d'abord pensé à un flush sur cout, mais ca n'a pas eu d'effet, apres je me suis dit que dans ma boucle quand je lis les entiers, il lit 2 fois le dernier entier car le fichier doit se terminer par un \n\0. je suppose qu'il garde dans un tampon le dernier entier lu et qu'il l'affiche une deuxieme fois.
j'ai fait plusieurs tests et je n'arrive vraiment pas a debugger ce probleme, quelqu'un a une solution ?
extrait du code (avec qq commentaires) :
déclaration de classe:
implémentation du code fautif:
je vous remercie d'avance