Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1457 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Lecture d'un fichier en mode binaire

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Lecture d'un fichier en mode binaire

n°1050351
noonio
Posté le 17-04-2005 à 22:40:38  profilanswer
 

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:

Code :
  1. class Fichier { //classe fichier
  2. public:
  3. Fichier(char*); //constructeur avec String
  4. Fichier(); //constructeur par defaut
  5. ~Fichier(); //destructeur
  6. void Ecrire(int); //ecrire un int
  7. int saisirEntier(void); //saisir une suite d'entiers
  8. void lire(void); //lire un fichier
  9. void rang(void); //lire un entier dont on connait le rang
  10. private: //membres privés
  11. ofstream ficOut; //descripteur pour ecrire..
  12. ifstream ficIn; //descripteur pour lire..
  13. };


 
implémentation du code fautif:

Code :
  1. void Fichier::lire(void) { //méthode permettant de lire un fichier existant, ouverture en binaire
  2. int entier;
  3. char fichier[20];
  4. cout << "saisir le nom du fichier a ouvrir (max 20 car): ";
  5. cin >> fichier; //saisie du chemin / nom
  6. ficIn.open(fichier, ios::binary); //ouverture du descripteur
  7. if(ficIn.is_open() == 0) {
  8.  cout << "erreur d'ouverture du fichier !\n";
  9.  return;
  10. }
  11. while(!ficIn.eof()) { //tant qu'on est pas a la fin du descripteur
  12.  ficIn >> entier; //on recupere les entiers avec l'opérateur >>  surchargé
  13.  cout << entier << endl; //puis affichage
  14. }
  15. cout.flush(); //flush de cout
  16. ficIn.close(); //fermeture de ficIn
  17. }


 
je vous remercie d'avance ;)

mood
Publicité
Posté le 17-04-2005 à 22:40:38  profilanswer
 

n°1050356
Taz
bisounours-codeur
Posté le 17-04-2005 à 22:47:54  profilanswer
 

# 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

n°1050360
noonio
Posté le 17-04-2005 à 22:51:58  profilanswer
 

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 :/


Message édité par noonio le 17-04-2005 à 22:55:44
n°1050364
Taz
bisounours-codeur
Posté le 17-04-2005 à 22:57:47  profilanswer
 

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 }

n°1050366
Taz
bisounours-codeur
Posté le 17-04-2005 à 23:01:29  profilanswer
 

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 :
  1. std::vector<int> entiers;
  2. int entier;
  3. while(in >> entier) { entiers.push_back(entier); }


 
voire

Code :
  1. std::copy(std::istream_iterator<int>(in), std::istream_iterator<int>(), std::back_inserter(entiers));

n°1050368
noonio
Posté le 17-04-2005 à 23:04:26  profilanswer
 

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

n°1050370
Taz
bisounours-codeur
Posté le 17-04-2005 à 23:08:37  profilanswer
 

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 ?

n°1050374
noonio
Posté le 17-04-2005 à 23:15:22  profilanswer
 

ben un fichier binaire pur juste.

n°1050375
noonio
Posté le 17-04-2005 à 23:17:23  profilanswer
 

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


Message édité par noonio le 17-04-2005 à 23:18:03
n°1050377
Taz
bisounours-codeur
Posté le 17-04-2005 à 23:19:10  profilanswer
 

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.

mood
Publicité
Posté le 17-04-2005 à 23:19:10  profilanswer
 

n°1050380
noonio
Posté le 17-04-2005 à 23:21:12  profilanswer
 

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?
 

n°1050384
Taz
bisounours-codeur
Posté le 17-04-2005 à 23:25:17  profilanswer
 

bon, on reprends depuis le début : ton fichier tu veux qu'il soit lisible avec notepad ou pas ?

n°1050385
noonio
Posté le 17-04-2005 à 23:25:39  profilanswer
 

ben non justement je veux un binaire tout moche

n°1050386
Taz
bisounours-codeur
Posté le 17-04-2005 à 23:29:22  profilanswer
 

alors ni '\n' ni >>. Pas la peine de tout stocker dans un tableau (sauf raison d'efficacité)
 

Code :
  1. if(!cin.seekg(index * sizeof integer)) { erreur }
  2. if(!cin.read(reinterpret_cast<char*>(&integer), sizeof integer)) { erreur }
  3. // voilà, tu as lu l'entier à l'<index>


 
ne fais ni trunc, ni rien. juste un ifstream("...", ios::binary) et c'est tout.

n°1050389
noonio
Posté le 17-04-2005 à 23:34:10  profilanswer
 

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 !

n°1050391
Taz
bisounours-codeur
Posté le 17-04-2005 à 23:40:57  profilanswer
 

istream.read / ostream.write
istream.seekg / istream.tellg
ostream.seekp / ostream.tellp


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Lecture d'un fichier en mode binaire

 

Sujets relatifs
comparer 2 fichier excelprotéger un fichier compressé
transfert de fichier texte avec des socketsMacro graphe Excel données importées de fichier .txt
lecture/écriture binaire (depuis URL) [Résolu][SCRIPT] recuperation d information dans une fichier TXT
Question sur upload de fichierCompiler un fichier batch ?
Pb safe_mode et safe_mode_exec_dir 
Plus de sujets relatifs à : Lecture d'un fichier en mode binaire


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR