OVH Cloud OVH Cloud

ifstream : pb avec seekg, début de fichier

2 réponses
Avatar
KooK
Salut,

Mon problème était qu'après avoir lu un fichier avec un "while(getline(...))",
la commande "seekg(0,ios::beg)" ne fonctionnait pas.

Après une recherche dans le groupe, j'ai résolu mon pb en mettant un
"fe.clear()" avant le seekg. Maintenant j'aimerai comprendre ce qui se passe.

-------------------------------
voilà mon code :
#include <fstream>
#include <iostream>

using namespace std;

void lire_fichier(ifstream &fe)
{
string ptr;
while(getline(fe,ptr))
cout << ptr << endl;
}

int main (int argc, char** argv)
{
ifstream fe("test.cpp");

if(!fe)
{
cerr << "fichier non ouvert\n";
exit(1);
}

fe.seekg(0, std::ios_base::end); //ca marche
cout << "1e passe : " << endl;
lire_fichier(fe);
//on revient au début du fichier
fe.clear();
fe.seekg(0, std::ios_base::beg); //<-- marche si clear()
// fe.seekg(0, std::ios::beg); //<-- marche pas non plus
cout << "2e passe : " << endl;
lire_fichier(fe);
}

Résultats :
1e passe :
2e passe :

---------------
J'ai ajouté :
fe.exceptions(ios::failbit, ios::badbit);
juste avant le premier seekg.

Voilà ce que j'obtiens :
1e passe :
terminate called after throwing an instance of 'std::ios_base::failure'
what() : basic_ios::clear
Aborted

Est-ce que la lecture de fin de fichier provoque une erreur ?
Comment lire plusieurs fois une même fichier proprement ?
des explications, liens sont les bienvenus.

KooK

2 réponses

Avatar
kanze
KooK wrote:

Mon problème était qu'après avoir lu un fichier avec un
"while(getline(...))", la commande "seekg(0,ios::beg)" ne
fonctionnait pas.

Après une recherche dans le groupe, j'ai résolu mon pb en
mettant un "fe.clear()" avant le seekg. Maintenant j'aimerai
comprendre ce qui se passe.

-------------------------------
voilà mon code :
#include <fstream>
#include <iostream>


#include <string>
aussi.

using namespace std;

void lire_fichier(ifstream &fe)
{
string ptr;
while(getline(fe,ptr))
cout << ptr << endl;
}

int main (int argc, char** argv)
{
ifstream fe("test.cpp");

if(!fe)
{
cerr << "fichier non ouvertn";
exit(1);
}

fe.seekg(0, std::ios_base::end); //ca marche


C'est normal, on n'a rien encore fait.

cout << "1e passe : " << endl;
lire_fichier(fe);


En sortie, on aurait normalement le eofbit et le failbit de
positionné. L'un ou l'autre fait que toute opération qui suit
échoue.

//on revient au début du fichier
fe.clear();
fe.seekg(0, std::ios_base::beg); //<-- marche si clear()
// fe.seekg(0, std::ios::beg); //<-- marche pas non plus


Comment, ça ne marche pas ? Ça doit appeler exactement la même
fonciton avec exactement les mêmes paramètres.

cout << "2e passe : " << endl;
lire_fichier(fe);
}

Résultats :
1e passe :
2e passe :


Et qu'est-ce qu'il y avait dans le fichier ? Je me serais
attendu à le voir dans la deuxième passe.

---------------
J'ai ajouté :
fe.exceptions(ios::failbit, ios::badbit);
juste avant le premier seekg.

Voilà ce que j'obtiens :
1e passe :
terminate called after throwing an instance of 'std::ios_base::failure'
what() : basic_ios::clear
Aborted

Est-ce que la lecture de fin de fichier provoque une erreur ?


C'est comme ça, effectivement, qu'on reconnaît être arrivé à la
fin en C++. On essaie de lire, et il n'y a rien de plus à lire.

Comment lire plusieurs fois une même fichier proprement ?


Le plus proprement, ça serait de le réouvrir chaque fois, avec
un nouveau ifstream. Sinon, clear() et le seekg() doit faire
l'affaire.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
KooK
KooK wrote:

fe.seekg(0, std::ios_base::end); //ca marche


C'est normal, on n'a rien encore fait.
Ce que je voulais dire, c'est que ça place bien le pointeur en fin de

fichier.
cout << "1e passe : " << endl;
lire_fichier(fe);


En sortie, on aurait normalement le eofbit et le failbit de
positionné. L'un ou l'autre fait que toute opération qui suit
échoue.

//on revient au début du fichier
fe.clear();
fe.seekg(0, std::ios_base::beg); //<-- marche si clear()
// fe.seekg(0, std::ios::beg); //<-- marche pas non plus


Comment, ça ne marche pas ? Ça doit appeler exactement la même
fonciton avec exactement les mêmes paramètres.
Oui, c'est la même chose, ça ne marche qu'avec le 'clear()', désolé un

reste de commentaire obsolète.

cout << "2e passe : " << endl;
lire_fichier(fe);
}

Résultats :
1e passe :
2e passe :


Et qu'est-ce qu'il y avait dans le fichier ? Je me serais
attendu à le voir dans la deuxième passe.
Re-désolé, c'est le résultat d'avant l'introduction du clear().

Le fichier s'affiche en 2e passe (il s'agit en fait du fichier source).
---------------
J'ai ajouté :
fe.exceptions(ios::failbit, ios::badbit);
juste avant le premier seekg.

Voilà ce que j'obtiens :
1e passe :
terminate called after throwing an instance of 'std::ios_base::failure'
what() : basic_ios::clear
Aborted

Est-ce que la lecture de fin de fichier provoque une erreur ?


C'est comme ça, effectivement, qu'on reconnaît être arrivé à la
fin en C++. On essaie de lire, et il n'y a rien de plus à lire.

Comment lire plusieurs fois une même fichier proprement ?


Le plus proprement, ça serait de le réouvrir chaque fois, avec
un nouveau ifstream. Sinon, clear() et le seekg() doit faire
l'affaire.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Merci d'avoir pris le temps de répondre.

KooK