OVH Cloud OVH Cloud

fstream problème avec écriture et lecture

14 réponses
Avatar
Markus
Bonjour,

mon problème : une classe permettan de lire et écrire dans un même fichier.


class c_File
{
public :
fstream fs;
.....
public :
...
friend void operator >> (c_File& ,string& );
friend void operator << (c_File& ,const char * );
...
}
void operator <<(c_File& myFile, const char* out )
{
myFile.fs<<out;
}
void operator >>(c_File& myFile, string& out)
{
int c;
string s; // Ich weiss !! ich könnte getline nehmen!!!
getline(myFile.fs,s);
out=s;
}

main.C
{
c_File oFile;
string s;
oFile.OpenFile("hugo.txt",ios::in|ios::out|ios::app );
oFile<<"hey baby!";
oFile>>s;
cout<<s<<endl;
}

Le résultat est :
(A l'origine le fichier est vide)
a l'écran : RIEN dans le fichier : hey baby!

pourquoi RIEN ? (ne s'affiche à l'écran)

J 'ai essayé avec, entre l'appel entre les deux operateur << et >>, les
methode seekp/seekg(0,ios::end), flush et sync ...
rien à faire.
A mon avis c'est un bogue de xlC ?
unix . aix 5.2 xlC version 6

merci beaucoup pour votre aide.

10 réponses

1 2
Avatar
Thomas Abbé
javais le meme probleme avec MSVC++ 6
workaround:
fstream pas utiliser comme membre
thomas

"Markus" schrieb im Newsbeitrag
news:bq4gca$u6v$

Bonjour,

mon problème : une classe permettan de lire et écrire dans un même
fichier.



class c_File
{
public :
fstream fs;
.....
public :
...
friend void operator >> (c_File& ,string& );
friend void operator << (c_File& ,const char * );
...
}
void operator <<(c_File& myFile, const char* out )
{
myFile.fs<<out;
}
void operator >>(c_File& myFile, string& out)
{
int c;
string s; // Ich weiss !! ich könnte getline nehmen!!!
getline(myFile.fs,s);
out=s;
}

main.C
{
c_File oFile;
string s;
oFile.OpenFile("hugo.txt",ios::in|ios::out|ios::app );
oFile<<"hey baby!";
oFile>>s;
cout<<s<<endl;
}

Le résultat est :
(A l'origine le fichier est vide)
a l'écran : RIEN dans le fichier : hey baby!

pourquoi RIEN ? (ne s'affiche à l'écran)

J 'ai essayé avec, entre l'appel entre les deux operateur << et >>, les
methode seekp/seekg(0,ios::end), flush et sync ...
rien à faire.
A mon avis c'est un bogue de xlC ?
unix . aix 5.2 xlC version 6

merci beaucoup pour votre aide.





Avatar
kanze
"Markus" wrote in message
news:<bq4gca$u6v$...

mon problème : une classe permettan de lire et écrire dans un même fichier.

class c_File
{
public :
fstream fs;
.....
public :
...
friend void operator >> (c_File& ,string& );
friend void operator << (c_File& ,const char * );

...
}
void operator <<(c_File& myFile, const char* out )
{
myFile.fs<<out;
}
void operator >>(c_File& myFile, string& out)
{
int c;
string s; // Ich weiss !! ich könnte getline nehmen!!!
getline(myFile.fs,s);
out=s;
}

main.C
{
c_File oFile;
string s;
oFile.OpenFile("hugo.txt",ios::in|ios::out|ios::app );
oFile<<"hey baby!";
oFile>>s;
cout<<s<<endl;
}

Le résultat est :
(A l'origine le fichier est vide)
a l'écran : RIEN dans le fichier : hey baby!

pourquoi RIEN ? (ne s'affiche à l'écran)


Parce que tu n'as rien affiché à l'écran.

En fait, je crois que ton problème vient d'une mauvaise compréhension de
comment fonction un fstream. Un fstream ne maintient qu'un seul pointeur
de position, qui sert à la fois à l'écriture et à la lecture. Après une
opération d'entrée ou de sortie, il est positionné au caractère suivant,
de façon à ce que la prochaine opération (du même type) se fait
correctement. Si le fichier est vide au départ, et tu fais « oFile <<
"Hey baby!" », le pointeur serait toujours positionné après le "Hey
baby!", à la fin du fichier, de façon à ce que la prochaine écriture ne
vient pas écraser ce que tu venais d'écrire. Si tu avais tester l'état
de la lecture, tu aurais vu tout de suite qu'il a rencontré la fin de
fichier.

Dans l'ensemble, les flux sont avant tout des flux -- c-à-d des sources
ou des destinations séquentielles uni-directionnelles. Leur interface
est conçue en fonction de cette utilisation. Des autres possibilités,
comme l'utilisation bi-directionnelle ou à accès aléatoire, existent,
mais elles exigent toujours un peu plus d'effort. Donc, par exemple,
dans un flux bi-directionnel, il faut prèsque toujours faire un seek
avant de changer la direction -- je connais peu d'applications où on
veut écrire immédiatement derrière ce qu'on vient de lire, et aucune où
on veut faire le contraire -- lire immédiatement derrière ce qu'on vient
d'écrire. Je ne suis pas sur de tête non plus les règles de flush dans
le cas des flux bi-directionnel. Aussi, il faut systèmatiquement
surveiller l'état -- si on vient d'arriver à la fin de fichier en
entrée, par exemple, la prochaine opération va échouer, quoiqu'elle
soit, au moins qu'on ne remette pas l'état à bon avec un clear().

Si ton but est simplement de lire en différé, séquentiellement, derrière
ce que tu as écrit, la meilleur solution, c'est d'utiliser deux flux :
un ofstream pour écrire, et un ifstream complètement séparé pour
écrire. Sans oublié les flush chaque fois que tu finis une écriture, et
des clear chaque fois que tu as lu fin de fichier. Et encore, je ne suis
pas sûr que ça marche avec toutes les implémentations. La gestion des
fin de fichiers dans les flux C++ n'est pas bien spécifiée, et varie
d'une implémentation à l'autre. Le problème, c'est que les flux délègue
les entrées/sorties physiques à un streambuf, et que le streambuf n'a
pas d'état accessible -- c-à-d que même si tu fais clear() au niveau du
flux, ce n'est pas dit que le filebuf (le streambuf pour les fichiers)
n'ait pas mémorisé l'état aussi. (Sous Unix, il est prèsqu'obligé de le
mémoriser afin d'avoir un comportement « normal » sur les entrées
clavier.)

Si tu veux réelement avoir un flux bi-directionnel avec deux pointeurs
distincts, un pour les entrées, un pour les sorties, il faudra que tu
gère les pointeurs toi-même -- chaque fois que tu changes de direction,
il faut d'abord sauver la position (obtenu au moyen de tellg ou tellp),
puis faire un seek (seekg ou seekp) à l'autre position.

J 'ai essayé avec, entre l'appel entre les deux operateur << et >>,
les methode seekp/seekg(0,ios::end), flush et sync ...
rien à faire.
A mon avis c'est un bogue de xlC ?
unix . aix 5.2 xlC version 6


Peut-être un bogue de la norme:-). Mais en fait, j'aurais tendance à
dire que les flux n'ont pas été conçu pour ça. Il y a bien quelques
fonctions qui donne l'air de le supporter, mais dans l'ensemble, elles
ne suffisent pas, et l'organisation de la gestion d'erreur ne le permet
pas à tous les coups non plus.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
Benoit Rousseau
wrote:

En fait, je crois que ton problème vient d'une mauvaise compréhension de
comment fonction un fstream. Un fstream ne maintient qu'un seul pointeur
de position, qui sert à la fois à l'écriture et à la lecture.


Justement à ce sujet (plusieur pointeurs) :
Lors d'un cours de parseur, on avait étudié un parseur assez simple (en
Haskell), mais efficace.

Il lancait plusieurs "threads" (simulés) en parallèle pour parser toutes
les différentes possibilités. Un thread qui n'acceptaient pas les
caractères du flux abandonnaient rapidement, alors que celui qui
acceptait la solution continuait gaiment sa route et lançait d'autres
threads pour parser la suite.

On pourrait voir ça en C++ comme un flux avec plusieurs pointeurs, non ?
Evidemment, il faudrait programmer toute la librairie, et Haskell était
plus adapté à ce genre de résolution (La paresse éliminant le début du
flux qui n'était plus nécessaire et la facilité de créer un langage
"embarqué" pour les "threads" étaient bien des avantages).

Est ce que cette idée d'appliquer ca au C++ est complétement idiote ?


--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16



--
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/

Avatar
kanze
Benoit Rousseau wrote in message
news:<3fcdab6a$0$2871$...
wrote:

En fait, je crois que ton problème vient d'une mauvaise
compréhension de comment fonction un fstream. Un fstream ne
maintient qu'un seul pointeur de position, qui sert à la fois à
l'écriture et à la lecture.


Justement à ce sujet (plusieur pointeurs) :
Lors d'un cours de parseur, on avait étudié un parseur assez simple
(en Haskell), mais efficace.

Il lancait plusieurs "threads" (simulés) en parallèle pour parser
toutes les différentes possibilités. Un thread qui n'acceptaient pas
les caractères du flux abandonnaient rapidement, alors que celui qui
acceptait la solution continuait gaiment sa route et lançait d'autres
threads pour parser la suite.

On pourrait voir ça en C++ comme un flux avec plusieurs pointeurs, non ?


Ça dépend de l'implémentation. La seule solution que je vois avec les
fstream, c'est de rouvrir le fichier de nouveau pour chaque thread, en
faisant un tellg sur l'ancien, et un seekg sur le nouveau, pour partir
du même endroit. Ce qui risque d'être assez cher.

Evidemment, il faudrait programmer toute la librairie, et Haskell
était plus adapté à ce genre de résolution (La paresse éliminant le
début du flux qui n'était plus nécessaire et la facilité de créer un
langage "embarqué" pour les "threads" étaient bien des avantages).

Est ce que cette idée d'appliquer ca au C++ est complétement idiote ?


Pas forcément.

D'abord, évidemment, il ne rapporte réelement que s'il y a plusieurs
processeurs ; sinon, le parallelisme n'est qu'apparant, et on paie les
changements de contexte en plus. Aussi, je soupçonne que ça ne se
justifiera que dans les cas où il y a une véritable ambiguïté possible
(mais ce n'est pas rare en C++) -- je ne lancerais pas un thread pour
chaque type d'instruction possible, sans en avoir regarder le premier
token : si c'est un if ou un while, par exemple, ce n'est pas la peine
de lancer un thread pour parser une declaration.

Ensuite, le « flux » que j'utiliserais dans les threads, ce serait un
flux de tokens en provenance du préprocesseur, et non un fstream. Du
coup, évidemment, je m'arrangerai pour que ça marche comme je veux.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Jean-Marc Bourguet
writes:

[...]

Bizarre comme on peut avoir des idees differentes. Quand il a parle
de threads simulees differentes, j'ai imagine la structure suivante:
on lit un symbole qu'on passe a tous les analyseurs gramaticaux
actifs. En recevant un symbole, un analyseur peut le refuser (et donc
se detruire) ou l'accepter. S'il l'accepte et qu'il y a un choix,
l'analyseur se clone pour poursuivre tous les choix simultanements.

C'est une structure capable d'analyser toutes les grammaires non
ambigues. Il y a deux problemes: la gestion des actions semantiques
et la gestion des erreurs.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
kanze
Jean-Marc Bourguet wrote in message
news:...
writes:

[...]

Bizarre comme on peut avoir des idees differentes. Quand il a parle
de threads simulees differentes, j'ai imagine la structure suivante:
on lit un symbole qu'on passe a tous les analyseurs gramaticaux
actifs. En recevant un symbole, un analyseur peut le refuser (et donc
se detruire) ou l'accepter. S'il l'accepte et qu'il y a un choix,
l'analyseur se clone pour poursuivre tous les choix simultanements.


En effet, ça a l'air intéressant. Mais quel rapport avec sa question de
base : un flux (fstream) qui maintenait plusieurs pointeurs différents
(un par thread) ?

C'est une structure capable d'analyser toutes les grammaires non
ambigues. Il y a deux problemes: la gestion des actions semantiques
et la gestion des erreurs.


Si les actions sémantiques ne sont pas irrévocables, je ne vois pas trop
de problème. Dans beaucoup de cas, l'action sémantique ne fait que
construire un arbre -- dans ce cas-là, c'est facile à jeter l'arbre
quand le thread échoue, et ne prendre en compte que l'arbre d'un des
threads à la fin.

Côté gestion des erreurs, c'est autre chose.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
kanze
Jean-Marc Bourguet wrote in message
news:...
writes:

[...]

Bizarre comme on peut avoir des idees differentes. Quand il a parle
de threads simulees differentes, j'ai imagine la structure suivante:
on lit un symbole qu'on passe a tous les analyseurs gramaticaux
actifs. En recevant un symbole, un analyseur peut le refuser (et donc
se detruire) ou l'accepter. S'il l'accepte et qu'il y a un choix,
l'analyseur se clone pour poursuivre tous les choix simultanements.


En effet, ça a l'air intéressant. Mais quel rapport avec sa question de
base : un flux (fstream) qui maintenait plusieurs pointeurs différents
(un par thread) ?

C'est une structure capable d'analyser toutes les grammaires non
ambigues. Il y a deux problemes: la gestion des actions semantiques
et la gestion des erreurs.


Si les actions sémantiques ne sont pas irrévocables, je ne vois pas trop
de problème. Dans beaucoup de cas, l'action sémantique ne fait que
construire un arbre -- dans ce cas-là, c'est facile à jeter l'arbre
quand le thread échoue, et ne prendre en compte que l'arbre d'un des
threads à la fin.

Côté gestion des erreurs, c'est autre chose.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
Jean-Marc Bourguet
writes:

Jean-Marc Bourguet wrote in message
news:...
writes:

[...]

Bizarre comme on peut avoir des idees differentes. Quand il a parle
de threads simulees differentes, j'ai imagine la structure suivante:
on lit un symbole qu'on passe a tous les analyseurs gramaticaux
actifs. En recevant un symbole, un analyseur peut le refuser (et donc
se detruire) ou l'accepter. S'il l'accepte et qu'il y a un choix,
l'analyseur se clone pour poursuivre tous les choix simultanements.


En effet, ça a l'air intéressant. Mais quel rapport avec sa question de
base : un flux (fstream) qui maintenait plusieurs pointeurs différents
(un par thread) ?


Aucun. De toute facon, je ne vois aucun interet a ne pas partager le
travail de l'analyseur lexical.

C'est une structure capable d'analyser toutes les grammaires non
ambigues. Il y a deux problemes: la gestion des actions semantiques
et la gestion des erreurs.


Si les actions sémantiques ne sont pas irrévocables, je ne vois pas trop
de problème. Dans beaucoup de cas, l'action sémantique ne fait que
construire un arbre -- dans ce cas-là, c'est facile à jeter l'arbre
quand le thread échoue, et ne prendre en compte que l'arbre d'un des
threads à la fin.


Passer son temps a dupliquer des arbres pour les jeter apres me semble
assez moyen si les arbres representent tout ce qui a ete parse jusqu'a
present. Imagine un programme normal ou on vient de parser la moitie
des en-tetes de la bibliotheques standards plus ceux du programme...
Mais bon ce n'est pas un probleme sans solutions, juste quelque chose
a quoi il faut penser.

Cette structure n'est d'ailleurs qu'une parallelisation des parseurs
qui travaillent par backtracking.

Côté gestion des erreurs, c'est autre chose.


Ce n'est pas non plus un probleme irremediable. On peut considerer
que le dernier parseur a disparaitre est le seul a emettre un message.
Ce n'est pas le seul message possible -- s'il y a eu plusieurs qui
sont arrives au meme point -- mais c'est de toute maniere pas tres
different que ce qui est fait avec les autres techniques qui sont
rares a donner des messages dans un prefixe viable meme si c'est celui
qu'aurait donne un humain.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.htm
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Gabriel Dos Reis
writes:

| > C'est une structure capable d'analyser toutes les grammaires non
| > ambigues. Il y a deux problemes: la gestion des actions semantiques
| > et la gestion des erreurs.
|
| Si les actions sémantiques ne sont pas irrévocables, je ne vois pas trop
| de problème. Dans beaucoup de cas, l'action sémantique ne fait que
| construire un arbre -- dans ce cas-là, c'est facile à jeter l'arbre
| quand le thread échoue, et ne prendre en compte que l'arbre d'un des
| threads à la fin.

sauf quand on parse C++ -- qui est un bon exemple de langage qui
impose le back-tracking. Et da'près l'avis des différents fabricants
de compilateur (surtout ceux de EDG compris), cela n'est pas du tout
facile comme tu prétents (et ton "beaucoup de cas" est en fait *peu*,
du moins si tu considères que C++ a des templates).

-- Gaby
Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

[...]

| > Côté gestion des erreurs, c'est autre chose.
|
| Ce n'est pas non plus un probleme irremediable.

cela dépend de la qualité que tu veux. Le nouveau parseur C++ a
d'abord essayé quelque chose come tu décris et cela a conduit à de la
confusion dans beaucoup trop de cas, et finalement l'idée a été
abandonnée.

-- Gaby
1 2