mikrocontroller.net

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


Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
FILE *logfile;

logfile = fopen("log.txt","w");
fprintf(logfile, "TEST\n");

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

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Hast du das File auch wieder geschlossen?

MfG Spess

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Imho fehlt nur das schliessen.

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

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der Prozeß ordnungsgemäß terminiert, sollten offene Files 
automatisch geschlossen werden.

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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... und in C++ hoffentlich ebenfalls :-)

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@yalu:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: franzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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");

Autor: Guile Lampert (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: franzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.