Forum: PC-Programmierung C++: Kann Daten in Datei nicht schreiben


von Jochen (Gast)


Lesenswert?

Ich möchte Daten in eine Textdatei abspeichern. Ich verwende die 
Software Microsoft Visual Studio .Net 2003. Die Textdatei log.txt habe 
ich bereits angelegt.
1
FILE *logfile;
2
3
logfile = fopen("log.txt","w");
4
fprintf(logfile, "TEST\n");

Die Datei ist nach dem Programmaufruf noch leer. Das verstehe ich nicht.
Kann mir jemand dazu Helfen?

von Uhu U. (uhu)


Lesenswert?

Bist du sicher, daß das aktuelle Verzeichnis das ist, in dem deine Datei 
liegt?
Hast du logfile geprüft, ob es != NULL ist?
Hast du das Programm regulär beendet? Ist sie ordnungsgemäß geschlossen 
worden?

Im Zweifel ist filemon ein gutes Diagnosewerkzeug.

von spess53 (Gast)


Lesenswert?

Hi

Hast du das File auch wieder geschlossen?

MfG Spess

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Imho fehlt nur das schliessen.

Allerdings verstehe ich nicht warum man sich das Leben unter C++ nicht 
angenehmer macht:
1
ofstream logfile("log.txt");
2
logfile << "TEST\n";
3
logfile.close();

von Uhu U. (uhu)


Lesenswert?

Wenn der Prozeß ordnungsgemäß terminiert, sollten offene Files 
automatisch geschlossen werden.

Wenn er vorher abstürzt, natürlich nicht.

von Rolf Magnus (Gast)


Lesenswert?

Automatisch geschlossen werden sie unter auf PCs üblichen 
Betriebssystemen eigentlich immer. Nur gibt es meistens in der 
Standardbibliothek noch einen Puffer, um die Anzahl der Schreibzugriffe 
zu minimieren, und dieser Puffer ist, wenn die Datei nicht vom Programm 
geschlossen wird, evtl. noch nicht rausgeschrieben worden, und zwar 
auch, wenn der Prozess ordnungsgemäß beendet wurde.

von yalu (Gast)


Lesenswert?

> und dieser Puffer ist, wenn die Datei nicht vom Programm geschlossen
> wird, evtl. noch nicht rausgeschrieben worden, und zwar auch, wenn
> der Prozess ordnungsgemäß beendet wurde.

Wenn das Programm normal, d.h. über exit() oder einen return in main()
beendet wird, werden alle stdio-Puffer von offenen Dateien
hinausgeschrieben und alle mit tmpfile() generierten Dateien gelöscht,
d.h. ein expliziter close() ist in vielen Fällen tatsäschlich nicht
erforderlich (aber dennoch empfehlenswert).

Wenn man das Programm gewaltsam killt, können natürlich Daten verloren
gehen.

von Rolf Magnus (Gast)


Lesenswert?

> Wenn das Programm normal, d.h. über exit() oder einen return in main()
> beendet wird, werden alle stdio-Puffer von offenen Dateien
> hinausgeschrieben

Sagt wer?

von yalu (Gast)


Lesenswert?

> Sagt wer?

Ich ;-). Die Herren vom ISO sind aber ganz ähnlicher Meinung:

  "The exit function causes normal program termination to occur. ...
  First ... . Next, all open streams with unwritten buffered data are
  flushed, all open streams are closed, and all files created by the
  tmpfile function are removed."

  "If the return type of the main function is a type compatible with
  int, a return from the initial call to the main function is
  equivalent to calling the exit function ..."

So ist's zumindest in C99. Was das Flushen und Schließen von Dateien
am Programmende betrifft, war dies m.W. auch in C90 schon so.

von yalu (Gast)


Lesenswert?

... und in C++ hoffentlich ebenfalls :-)

von Benedikt K. (benedikt)


Lesenswert?

yalu wrote:
> Wenn das Programm normal, d.h. über exit() oder einen return in main()
> beendet wird, werden alle stdio-Puffer von offenen Dateien
> hinausgeschrieben und alle mit tmpfile() generierten Dateien gelöscht,
> d.h. ein expliziter close() ist in vielen Fällen tatsäschlich nicht
> erforderlich (aber dennoch empfehlenswert).

Meiner Erfahrung nacht stimmt das nicht. Ich hatte mal ein kleines MFC 
Programm zusammengeklickt, das ein paar Werte mitprotokollierte. Am Ende 
fehlten immer die letzen paar hundert Bytes, wenn die Datei nicht 
richtig geschlossen wurde.

von Uhu U. (uhu)


Lesenswert?

Benedikt K. wrote:
> Meiner Erfahrung nacht stimmt das nicht. Ich hatte mal ein kleines MFC
> Programm zusammengeklickt, das ein paar Werte mitprotokollierte. Am Ende
> fehlten immer die letzen paar hundert Bytes, wenn die Datei nicht
> richtig geschlossen wurde.

Wenn eine App während des exit() abstürzt, kann es - zumindest bei den 
9x-Systemen - vorkommen, daß man nicht darauf hingewiesen wird. Es gibt 
dort so einige finstere Ecken, die selbst dem Debugger unzugänglich 
sind.

In der Regel funktioniert das implizite close aber ganz gut.

von Rolf Magnus (Gast)


Lesenswert?

@yalu:

Stimmt. Da habe ich mich wohl geirrt. Wieder was gelernt.

von Karl H. (kbuchegg)


Lesenswert?

Rolf Magnus wrote:
> @yalu:
>
> Stimmt. Da habe ich mich wohl geirrt. Wieder was gelernt.

War mir auch neu.
Allerdings plädiere ich immer noch für einen expliziten close,
bzw. die Verwendung der stream Klasse, die den close für einen
erledigen.

Das hat auch einen ganz einfachen Grund:
Irgendwann kommt der Tag, an dem man eine Funktionalität
aus einem Testprogramm weiterverwenden möchte. Was tun?
Ist doch simpel, main() umbenennen in einen vernünftigen
Funktionsnamen, compilieren, linken, läuft.
Das die Datei (da man sich auf das implizite close beim
Niederfahren der App() verlassen hat) noch stundenlang
geöffnet ist und ev. nicht geflusht wurde, weil der Programmierer
keinen close macht, merkt man dann erst nach Stunden der
Debugsitzung.

Vielleicht bin ich altmodisch, aber ich erwarte von einem
Industrieprogrammierer schon, dass er hinter sich aufräumt.
Dazu gehört: Speicher wieder freigeben, Files schliessen
und sonstige Resourcen (zb. Windows Handles) freigeben.
Alles andere ist für mich irgendwo ein Spiel mit dem Feuer.

von yalu (Gast)


Lesenswert?

> Vielleicht bin ich altmodisch, aber ich erwarte von einem
> Industrieprogrammierer schon, dass er hinter sich aufräumt.

Nee, das ist überhaupt nicht altmodisch. Außer dem von dir
geschilderten Problem verbrauchen offene Dateien auch Speicher für den
Puffer. Des Weiteren ist die Anzahl der offenen Dateien je Prozess und
systemweit bei den meisten Betriebssystemen limitiert. Ein Programm,
das immer wieder Dateien öffnet, ohne sie wieder zu schließen, führt
also früher oder später immer zum bösen Erwachen. Zwar meistens eher
später, aber dann umso heftiger ;-)

Deswegen habe ich in meinem ersten Post geschrieben: "... ein
expliziter close() ist in vielen Fällen tatsäschlich nicht
erforderlich (aber dennoch empfehlenswert)." Vielleicht hätte ich
statt "dennoch" besser "unbedingt" schreiben sollen.

Man spendiert ja auch jedem malloc() ein free(), obwohl der Speicher
beim Beenden des Pozesses vom Betriebssystem freigegeben wird.

von Benedikt K. (benedikt)


Lesenswert?

Uhu Uhuhu wrote:
> Benedikt K. wrote:
>> Meiner Erfahrung nacht stimmt das nicht. Ich hatte mal ein kleines MFC
>> Programm zusammengeklickt, das ein paar Werte mitprotokollierte. Am Ende
>> fehlten immer die letzen paar hundert Bytes, wenn die Datei nicht
>> richtig geschlossen wurde.
>
> Wenn eine App während des exit() abstürzt, kann es - zumindest bei den
> 9x-Systemen - vorkommen, daß man nicht darauf hingewiesen wird. Es gibt
> dort so einige finstere Ecken, die selbst dem Debugger unzugänglich
> sind.
>
> In der Regel funktioniert das implizite close aber ganz gut.

In der Regel ja, daher hatte ich darauf auch nicht geachtet, da ich 
vorher damit auch keine Probleme hatte (bzw diese nicht bemerkt habe). 
Nur dummerweiße ging das in dem eienn Fall nicht. Mit einem richtigen 
fclose() war das Problem behoben. Und das ganze war unter WinXP.

Jetzt mal ganz dumm gefragt: Woher weiß die Software eigentlich, dass 
beim Beenden noch Daten zu schreiben sind ?
Diese Infos stecken doch normalerweise in dem Filepointer, oder ?

von Rolf Magnus (Gast)


Lesenswert?

> Jetzt mal ganz dumm gefragt: Woher weiß die Software eigentlich, dass
> beim Beenden noch Daten zu schreiben sind ?

Sie kann sich ja merken, welche Dateien noch offen sind und nach dem 
Beenden von main diese Liste durchgehen und für jede ein close() 
aufrufen.

> Diese Infos stecken doch normalerweise in dem Filepointer, oder ?

Eher in einer internen Struktur, auf die dieser Pointer in der Regel 
zeigt.

von franzi (Gast)


Lesenswert?

Hallo,

ich hätte auch noch kurz eine Frage,
ich möchte in meinen Programm Daten in einer Datei einfügen, spricht 
immer hinten anhängen. wie ist da der Befehl für C++,

in c ist es ja:
pf = fopen("Text.txt", "a");

von Guile Lampert (Gast)


Lesenswert?

Versuch einfach mal mit flush das Schreiben der Daten in die Datei zu 
forcieren. Und vergiss nicht die Datei ordnungsgemäß zu schließen.

Wenn Du flush verwendest sollte auch ein Absturz des Programms nicht 
weiter wild sein. Vorausgesetzt natürlich, dass fprintf und flush noch 
ausgeführt wurden.

Gruss
Guild

von franzi (Gast)


Lesenswert?

hab jetzt was gefunden von der seite zum buch c++ von arnold wilmer

muss beim öffnen das schon eingeben:
wie folgt:

fstream datei ("text.txt", ios::app)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.