 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Ernst Baumann Guest
|
Posted: Tue Mar 07, 2006 10:46 pm Post subject: PROBLEM: Dateizeiger verschieben mit fseek |
|
|
Hallo allerseits,
Eigentlich eine einfach zu lösende Aufgabe:
In einer Datei (mit Inhalt "ABxC") soll das Zeichen x durch y ersetzt
werden.
Also gehe ich in einer Schleife alle Zeichen der Datei durch und wenn
man mit get(z) das Zeichen x gelesen hat und deshalb der Dateizeiger
dann auf das nächste Zeichen, also C, zeigt, wird der Datezeiger um 1
nach links verschoben und zeigt nun auf x. Dann schreibt man mit
put(z) das Zeichen y in die Datei (d.h. x wird durch y ersetzt).
Was ich aber dann nicht verstehe (mit Debugger nachgeprüft):
Nachdem das Zeichen y reingeschrieben wurde, müsste der Dateizeiger
eigentlich auf das nächste Zeichen C zeigen. Allerindings wird in der
Schleife als nächstes das Zeichen B eingelesen.
Kann mir jemand bitte erklären, was ich falsch mache ?
Oder ist das ein Problem des MS VC++Vers.6.0 Compilers ?
--------------------- Programm - Beginn -----------------------
#include "stdafx.h"
#include <string>
#include <iostream> // i/o
#include <fstream> // datei i/o
#include <string.h>
using namespace std;
int main(){
fstream quelle;
char z;
// Datei anlegen mit Inhalt ABxC
quelle.open("C:\\test.txt", ios::out|ios::app);
quelle.close();
quelle.open("C:\\test.txt",ios::in|ios::out|ios::trunc|ios::binary);
quelle <<"ABxC" << endl;
// Dateizeiger auf Dateianfang setzen
quelle.seekg(0, ios::beg);
while(quelle.get(z)){
if(z=='x'){
// Dateizeiger um 1 nach links verschieben
quelle.seekg(-1, ios::cur);
quelle.put('y');
}
}
// Jetzt Fehlerreport
if (!quelle.eof()){
if (quelle.bad())
cout << "Es gab ein technisches Problem\n"; // (*)
else
cout << "Format-Fehler!\n";
}
return(0);
}
--------------------- Programm - Ende -----------------------
mfg
Ernst
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Vinzenz 'evilissimo' Feen Guest
|
Posted: Wed Mar 08, 2006 2:06 pm Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek |
|
|
Ernst Baumann schrieb:
| Quote: | Hallo allerseits,
Eigentlich eine einfach zu lösende Aufgabe:
In einer Datei (mit Inhalt "ABxC") soll das Zeichen x durch y ersetzt
werden.
Also gehe ich in einer Schleife alle Zeichen der Datei durch und wenn
man mit get(z) das Zeichen x gelesen hat und deshalb der Dateizeiger
dann auf das nächste Zeichen, also C, zeigt, wird der Datezeiger um 1
nach links verschoben und zeigt nun auf x. Dann schreibt man mit
put(z) das Zeichen y in die Datei (d.h. x wird durch y ersetzt).
Was ich aber dann nicht verstehe (mit Debugger nachgeprüft):
Nachdem das Zeichen y reingeschrieben wurde, müsste der Dateizeiger
eigentlich auf das nächste Zeichen C zeigen. Allerindings wird in der
Schleife als nächstes das Zeichen B eingelesen.
Kann mir jemand bitte erklären, was ich falsch mache ?
Oder ist das ein Problem des MS VC++Vers.6.0 Compilers ?
|
Dein Problem ist das du nicht daran denkst, dass es 2 Dateizeiger gibt.
Einen zum lesen und einen zum schreiben.
Wenn du dir die Referenz zu fstream anschaust wirst du feststellen das
es seekg/tellg gibt und seekp/tellp
Alternativ könntest du natürlich auch die Methoden seekoff und seekpos
benutzen.
BR
Vinzenz 'evilissimo' Feenstra
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Dietmar Kuehl Guest
|
Posted: Wed Mar 08, 2006 3:06 pm Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek |
|
|
Vinzenz 'evilissimo' Feenstra wrote:
| Quote: | Dein Problem ist das du nicht daran denkst, dass es 2 Dateizeiger gibt.
Einen zum lesen und einen zum schreiben.
|
Nein, das ist nicht das Problem! Die beiden Dateizeiger sind immer
synchronisiert und an der gleichen Position. Das Problem ist, dass
man zwischen dem Wechsel von Input zu Output oder umgekehrt zwingend
einen "seek" einlegen muß, auch wenn dieser nichts macht. D.h. nach
dem 'put()' sollte eine Zeile der Form
quelle.seekg(0, std::ios::cur);
folgen. Allerdings kann ich bei mir das Problem nicht reproduzieren,
so dass ich auch nicht sagen kann, ob der Fix richtig ist...
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Ernst Baumann Guest
|
Posted: Wed Mar 08, 2006 7:06 pm Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek |
|
|
| Quote: | Vinzenz 'evilissimo' Feenstra wrote:
Dein Problem ist das du nicht daran denkst, dass es 2 Dateizeiger gibt.
Einen zum lesen und einen zum schreiben.
Nein, das ist nicht das Problem! Die beiden Dateizeiger sind immer
synchronisiert und an der gleichen Position. Das Problem ist, dass
man zwischen dem Wechsel von Input zu Output oder umgekehrt zwingend
einen "seek" einlegen muß, auch wenn dieser nichts macht. D.h. nach
dem 'put()' sollte eine Zeile der Form
quelle.seekg(0, std::ios::cur);
folgen. Allerdings kann ich bei mir das Problem nicht reproduzieren,
so dass ich auch nicht sagen kann, ob der Fix richtig ist...
es ist genauso so wie du es beschrieben hast !! |
Mit
----------------------------------------------------------------------------------
while(quelle.get(z)){
if(z=='x'){
quelle.seekg(-1, ios::cur);
quelle.put('y');
quelle.seekg(-1, ios::cur);
}
}
----------------------------------------------------------------------------------
funktioniert alles einwandfrei !!
Danke für diese wichtige Information.
Trotzdem noch ein paar Fragen:
1) Ist dieses Verhalten ein Fehler des Compilers ?
Ich meine ja.
2) Ist dieses Verhalten Microsoft-spezifisch ?
Warum kannst du dieses Verhalten bei dir (welcher Compiler) nicht
reproduzieren ?
3) Wo steht in der Hilfe zu MS VC++ Vers. 6.0 dieses Verhalten
beschrieben, bzw. (wenn es dort nicht beschrieben seht):
Wo gibt es einen Link (oder eine Doku) zu diesem Verhalten ?
mfg
Ernst
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Wed Mar 08, 2006 8:06 pm Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek |
|
|
Ernst Baumann wrote:
[zwischen read und write muss seek stehen]
| Quote: | Trotzdem noch ein paar Fragen:
1) Ist dieses Verhalten ein Fehler des Compilers ?
Ich meine ja.
|
Nein.
Wenn du zwischen Lesen und Schreiben wechselst, muss dazwischen ein seek
stehen. Tust du es nicht, ist das Verhalten deines Programmes undefiniert.
| Quote: | 2) Ist dieses Verhalten Microsoft-spezifisch ?
Warum kannst du dieses Verhalten bei dir (welcher Compiler) nicht
reproduzieren ?
|
Weil es bei ihm zufällig funktioniert.
| Quote: | 3) Wo steht in der Hilfe zu MS VC++ Vers. 6.0 dieses Verhalten
beschrieben, bzw. (wenn es dort nicht beschrieben seht):
Wo gibt es einen Link (oder eine Doku) zu diesem Verhalten ?
|
ISO-Standard.
ISO 14882:1998, 27.8.1.1p2: The restrictions on reading and writing a
sequence controlled by an object of class basic_filebuf<charT,traits>
are the same as for reading and writing with the Standard C library FILEs.
ISO 9899:1999 (den 1989er hab ich nicht), 7.19.5.3 [fopen] p6: [...]
However, output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning
function (fseek, fsetpos, or rewind), and input shall not be directly
followed by output without an intervening call to a file positioning
function, unless the input pperation encounters end-of-file.
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Dietmar Kuehl Guest
|
Posted: Wed Mar 08, 2006 8:06 pm Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek |
|
|
Ernst Baumann wrote:
| Quote: | Das Problem ist, dass
man zwischen dem Wechsel von Input zu Output oder umgekehrt zwingend
einen "seek" einlegen muß, auch wenn dieser nichts macht. D.h. nach
dem 'put()' sollte eine Zeile der Form
quelle.seekg(0, std::ios::cur);
folgen. Allerdings kann ich bei mir das Problem nicht reproduzieren,
so dass ich auch nicht sagen kann, ob der Fix richtig ist...
es ist genauso so wie du es beschrieben hast !!
|
Das ist nicht weiter verwunderlich: die Restriktion wurde vermutlich
von P.J.Plauger in den C Standard gebracht. Das ist derjenige, der
die Standard Bibliothek von MSVC++ implementiert hat.
| Quote: | 1) Ist dieses Verhalten ein Fehler des Compilers ?
Ich meine ja.
|
Nein. Der C Standard, und daher auch der C++ Standard, definiert
ziemlich klare Zustände für File Streams und welche Übergänge
zulässig sind. Der Wechsel zwischen Lesen und Schreiben ohne Seek
ist nicht erlaubt.
| Quote: | 2) Ist dieses Verhalten Microsoft-spezifisch ?
|
Nein. Man kann File-Stream implementieren, ohne diese Zusicherung,
aber dann sind sie ggf. weniger performant.
| Quote: | Warum kannst du dieses Verhalten bei dir (welcher Compiler) nicht
reproduzieren ?
|
Weil ich eine andere Standard C++ Bibliothek getestet habe
(libstdc++), die offenbar von der Zusicherung keinen gebrauch macht.
| Quote: | 3) Wo steht in der Hilfe zu MS VC++ Vers. 6.0 dieses Verhalten
beschrieben,
|
Keine Ahnung. Womöglich garnicht. Das Verhalten ist implizit im
C und C++ Standard enthalten. Sämtliche Textpassagen, aus denen
sich das ergibt, aufzuspüren ist allerdings wenig spaßig.
| Quote: | bzw. (wenn es dort nicht beschrieben seht):
Wo gibt es einen Link (oder eine Doku) zu diesem Verhalten ?
|
Die beste Doku ist das State-Diagram von P.J.Plauger:
<http://www.dinkumware.com/manuals/reader.aspx?b=c/&h=lib_file.html#Stream
States>. Gelegentlich produzieren die Links in der Dokumentation
eine Werbeseite (für Dinkumware Produkte, wie z.B. die Online-Doku).
Dann muß man es einfach nochmal versuchen.
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Thu Mar 09, 2006 6:06 pm Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek |
|
|
Dietmar Kuehl wrote:
| Quote: | Ernst Baumann wrote:
Das Problem ist, dass man zwischen dem Wechsel von Input zu
Output oder umgekehrt zwingend einen "seek" einlegen muß,
auch wenn dieser nichts macht. D.h. nach dem 'put()' sollte
eine Zeile der Form
quelle.seekg(0, std::ios::cur);
folgen. Allerdings kann ich bei mir das Problem nicht
reproduzieren, so dass ich auch nicht sagen kann, ob der Fix
richtig ist...
es ist genauso so wie du es beschrieben hast !!
Das ist nicht weiter verwunderlich: die Restriktion wurde
vermutlich von P.J.Plauger in den C Standard gebracht.
|
Es war eine gängige Restriction auf alten Unix. Was nicht
unbedingt heißt, dass es nicht ursprunglich von Plauger war; er
war unter den ersten, die Bibliotheke in C schrieb. Aber er
braucht nichts besonderes zu machen, dass sie in der C Standard
kommt; es war damals selbstverstsndlich, dass die Restrictionen
im Unix C bleiben.
| Quote: | Das ist derjenige, der die Standard Bibliothek von MSVC++
implementiert hat.
1) Ist dieses Verhalten ein Fehler des Compilers ? Ich
meine ja.
Nein. Der C Standard, und daher auch der C++ Standard,
definiert ziemlich klare Zustände für File Streams und welche
Übergänge zulässig sind. Der Wechsel zwischen Lesen und
Schreiben ohne Seek ist nicht erlaubt.
|
Für File Streams, wohl. Für Streams in allgemein sagt sie
(§27.5.1):
Stream buffers can impost various constraints on the
sequences they control. Some constraints are:
[...]
-- The controlled sequences can impose limitations on how
the program can read characters from a sequence, write
characters to a sequence, put characters back into an
input sequence, or alter the stream position.
Also, wenn du nur eine iostream& hast, und nicht weißt, was für
einen streabuf dahinten legt, kann es beliebige Restrictionen
geben; du kannst die aber nie wissen.
| Quote: | 2) Ist dieses Verhalten Microsoft-spezifisch ?
Nein. Man kann File-Stream implementieren, ohne diese
Zusicherung, aber dann sind sie ggf. weniger performant.
|
Eher, dass man den existierenden Code aus der C-Zeiten nicht
weiter benutzen kann, oder... Man spart höchst ein Paar
Zeiger-Zuweisungen, denke ich.
Ich gebe zu: ich habe eigentlich nie den Grund dieser
Restriction verstanden. Es war nicht in meiner Implementierung
der C-Bibliothek, zirka 1983. Und wann es nicht damals nötig
war, unter CP/M, finde ich es schwer zu glauben, dass es heute
unter einem modernen Betriebssystem nötig ist. Ich habe aber
genau das Verhalten von Ernst Baumann, heute in C unter Solaris.
Der Zustand der Unix-Bibliotheke scheint sich nicht verbessert
zu haben (und nachher enthält die Datei "AByB", statt "AByC").
--
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
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Ernst Baumann Guest
|
Posted: Fri Mar 10, 2006 2:07 pm Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek |
|
|
| Quote: | 1) Ist dieses Verhalten ein Fehler des Compilers ?
Ich meine ja.
Nein.
Wenn du zwischen Lesen und Schreiben wechselst, muss dazwischen ein seek
stehen. Tust du es nicht, ist das Verhalten deines Programmes undefiniert.
2) Ist dieses Verhalten Microsoft-spezifisch ?
Warum kannst du dieses Verhalten bei dir (welcher Compiler) nicht
reproduzieren ?
Weil es bei ihm zufällig funktioniert.
3) Wo steht in der Hilfe zu MS VC++ Vers. 6.0 dieses Verhalten
beschrieben, bzw. (wenn es dort nicht beschrieben seht):
Wo gibt es einen Link (oder eine Doku) zu diesem Verhalten ?
ISO-Standard.
ISO 14882:1998, 27.8.1.1p2: The restrictions on reading and writing a
sequence controlled by an object of class basic_filebuf<charT,traits
are the same as for reading and writing with the Standard C library FILEs.
ISO 9899:1999 (den 1989er hab ich nicht), 7.19.5.3 [fopen] p6: [...]
However, output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning
function (fseek, fsetpos, or rewind), and input shall not be directly
followed by output without an intervening call to a file positioning
function, unless the input pperation encounters end-of-file.
vielen Dank für eure wertvollen Informationen, Jetzt ist mir Vieles |
klarer. Allein hätte ich dieses Problem nicht gelöst.
mfg
Ernst
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|