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?
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.
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.
> 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.
> 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?
> 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.
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.
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.
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.
> 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.
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 ?
> 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.
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");
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
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)