# (C++) In Textdatei schreiben ohne Inhalt zu löschen



## the_undertaker (28. Juni 2007)

Hallo,

wenn ich mit fstream Daten in eine txt.-Datei schreibe, wird bei jedem Programmaufruf der bisherige Inhalt der Datei gelöscht. Wie kann man das verhindern?


----------



## Hallasas (28. Juni 2007)

Mit der Funktion *fopen*.
Syntax:

```
FILE * fopen ( const char * filename, const char * mode );
```

und sowohl *fwrite*.
Syntax:

```
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
```

Beispiel:

```
#include <stdio.h>

int main()
{
 FILE * myfile;
 char buffer[] = { 'x' , 'y' , 'z' };
 myfile = fopen( "meinedatei.txt" , "a+" );
 // a+ setzt den zeiger ans ende der datei...
 fwrite (buffer , sizeof(buffer[0]) , sizeof(buffer) , myfile );
 fclose(myfile);
 return 0;
}
```

Gruß Hallasas


----------



## the_undertaker (28. Juni 2007)

Danke für die schnelle Antwort!


----------



## Matthias Reitinger (28. Juni 2007)

Hallo,

man kann dem Konstruktor bzw. der open-Methode von fstream einen zweiten Parameter übergeben, der den Dateimodus bestimmt:

```
fstream filestr;
filestr.open("test.txt", ios::in | ios::out | ios::ate);
…
filestr.close();
```
ios::ate sorgt dafür, dass der Dateizeiger sofort nach dem Öffnen an das Ende der Datei gesetzt wird (*at e*nd). Alternativ kannst du auch von Hand den Zeiger an das Ende setzen:

```
fstream filestr;
filestr.open("test.txt", ios::in | ios::out);
filestr.seekg(0, ios::end);
...
filestr.close();
```

Grüße,
Matthias


----------



## Hallasas (28. Juni 2007)

So lernt man dazu...
Danke, Matthias!


----------



## the_undertaker (28. Juni 2007)

Matthias Reitinger hat gesagt.:


> Hallo,
> 
> man kann dem Konstruktor bzw. der open-Methode von fstream einen zweiten Parameter übergeben, der den Dateimodus bestimmt:
> 
> ...


Brauche ich dann noch fopen?


----------



## Hallasas (28. Juni 2007)

Eigentlich nicht.
Matthias hat dir die "fstream Methode" gezeigt, und ich dir die "file Methode".
Nun kannst du dich auf die dir am besten liegende Methode spezifizieren.

Gruß Hallasas


----------



## the_undertaker (29. Juni 2007)

Leider funktioniert deine Methode nicht, Matthias, die ursprünglichen Daten werden trotzdem gelöscht

Gibt es für fopen auch noch eine andere Möglichkeit als fwrite? (Am besten wär es, wenn man das so handhaben könnte wie cout, das ist nämlich schön einfach)

Hier mal meine Test-Fassung:
	
	
	



```
#include "stdafx.h"
#include <fstream>

using namespace std;

int main()
{
	fstream outfile;
	outfile.open("test.txt",ios::out|ios::ate);
	outfile<<"12345";
	outfile.close();
	return 0;
}
```


----------



## deepthroat (29. Juni 2007)

Hi.





the_undertaker hat gesagt.:


> Leider funktioniert deine Methode nicht, Matthias, die ursprünglichen Daten werden trotzdem gelöscht
> 
> Gibt es für fopen auch noch eine andere Möglichkeit als fwrite? (Am besten wär es, wenn man das so handhaben könnte wie cout, das ist nämlich schön einfach)
> 
> ...


Das sollte eigentlich genau so funktionieren. Welche Version von Visual Studio verwendest du denn?

Du kannst es ja einfach mit dem Alternativ-Vorschlag von Matthias versuchen.

Oder versuch erstmal den Modus "ios::in|ios:ut|ios::ate". Das klingt zwar für einen ofstream unlogisch den Modus "in" zu verwenden, aber siehe http://msdn2.microsoft.com/de-de/library/8h8eh904(vs.80).aspx


> Sie können ofstream-Objekte nicht mit dem ios:ut-Flag allein öffnen. Das ios:ut-Flag muss mit einem anderen ios-Enumerator in einem logischen OR-Befehl kombiniert werden, z. B. mit ios::in oder ios::app.



Gruß


----------



## the_undertaker (29. Juni 2007)

deepthroat hat gesagt.:


> Welche Version von Visual Studio verwendest du denn?


Visual C++ 2005 Express Edition


deepthroat hat gesagt.:


> Oder versuch erstmal den Modus "ios::in|ios:ut|ios::ate". Das klingt zwar für einen ofstream unlogisch den Modus "in" zu verwenden


Danke, jetzt klappts, es muss aber schon eine Textdatei vorhanden sein, es wird nicht einfach eine erstellt (macht aber nichts)


----------



## deepthroat (29. Juni 2007)

deepthroat hat gesagt.:


> Hi.
> Das sollte eigentlich genau so funktionieren. Welche Version von Visual Studio verwendest du denn?


Nein, da muß ich mich korrigieren. Das Verhalten ist völlig OK. Wenn du nur "ios:ut" angibst (das ios::ate spielt keine Rolle), wird die Datei im Schreibmodus geöffnet und der Dateiinhalt gelöscht. Die Angabe "ios:ut | ios::ate" ist demnach unsinnig, da nach dem Öffnen der Anfang und das Ende der Datei gleich sind.

Beim Modus "ios::in | ios:ut | ios::ate" wird tatsächlich keine Datei erstellt wenn sie noch nicht vorhanden ist. Man muß dafür die Datei erst mit "ios:ut | ios::app" öffnen - dann wird die Datei erstellt falls sie nicht existiert, ansonsten bleibt der Inhalt der Datei erhalten.

Gruß


----------



## the_undertaker (29. Juni 2007)

also reicht ios::ate und ich brauche sonst nichts?

edit: oder ios:ut|ios::app? ich probiers auch noch aus...


----------



## the_undertaker (29. Juni 2007)

Danke an alle, jetzt klappts!


----------

