C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

PROBLEM: Dateizeiger verschieben mit fseek

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Ernst Baumann
Guest





PostPosted: Tue Mar 07, 2006 10:46 pm    Post subject: PROBLEM: Dateizeiger verschieben mit fseek Reply with 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 ?




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





PostPosted: Wed Mar 08, 2006 2:06 pm    Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek Reply with quote



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





PostPosted: Wed Mar 08, 2006 3:06 pm    Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek Reply with quote



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





PostPosted: Wed Mar 08, 2006 7:06 pm    Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek Reply with quote

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





PostPosted: Wed Mar 08, 2006 8:06 pm    Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek Reply with quote

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





PostPosted: Wed Mar 08, 2006 8:06 pm    Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek Reply with quote

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





PostPosted: Thu Mar 09, 2006 6:06 pm    Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek Reply with quote

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





PostPosted: Fri Mar 10, 2006 2:07 pm    Post subject: Re: PROBLEM: Dateizeiger verschieben mit fseek Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.