# Array in Datei speichern



## JimboJT (4. Mai 2008)

Hallo,

ich habe mir aus dem Internet ein Beispiel heruntergeladen mit dem ich einen String in eine Txt File speichern kann. Ich wollte dieses Beispiel abändern das ich ein Array von meinem Programm darin speichern kann. Leider funktioniert es nicht mehr mit der Abänderung. Kann mir vllt. einer auf die Sprünge helfen.


```
Cstring speicherString[640];
long int dateilaenge [640];

// Dialog zum Speichern einer Datei
CFileDialog fileDlg(FALSE, ".txt", NULL, 0, "Textfile (*.txt)|*.txt|All Files (*.*)|*.*||");
 
fileDlg.DoModal();
 
CString pfad = fileDlg.GetPathName ();
 
CFile datei;
 
// Dies ist der String der gepeichert wird
for(i = 0; i < 640; i++)
{
	speicherString[i] = test[i];
                //test ist mein Array mit den Werten, die ich abspeichern möchte
	// Variable fuer die Dateilaenge erzeugen
	dateilaenge[i] = speicherString[i].GetLength ();
}

// Oeffnen der Datei zum Schreiben
datei.Open (fileDlg.GetPathName(), CFile::modeCreate | CFile::modeWrite);
 
// Inhalt des Strings in Datei schreiben
for (i = 0; i < 640; i++)
{
	datei.Write (speicherString[i], dateilaenge[i]);
}
// Schliessen der Datei
datei.Close ();
```

Danke für eure Mühe!


----------



## devDevil (4. Mai 2008)

(1) Schreib bitte dran dass es sich um MFC handelt. Danke.


```
const std::size_t count_elements(640);

CString arr_data_value[count_elements];
int arr_data_length [count_elements];

// Dialog zum Speichern einer Datei
CFileDialog dlg_filename(FALSE, TEXT(".txt"), NULL, 0, TEXT("Textfile (*.txt)|*.txt|All Files (*.*)|*.*||"));
fileDlg.DoModal();

const CString file_path(dlg_filename.GetPathName());

// Dies ist der String der gepeichert wird
for (std::size_t i(0); i < count_elements; ++i)
{
    arr_data_value[i] = test[i];
    arr_data_length[i] = test[i].GetLength();
}

// Öffnen der Datei zum Schreiben
CFile file;
file.Open (file_path, CFile::modeCreate | CFile::modeWrite);

// Inhalt des Strings in Datei schreiben
for (std::size_t i(0); i < count_elements; ++i)
{
    file.Write(arr_data_value[i], sizeof(arr_data_length[i]));
    file.Write(arr_data_value[i], arr_data_length[i] * sizeof(TCHAR));
}
// Schliessen der Datei
file.Close ();
```
 so sollte das doch gehen (dein Code vorher auch!) was geht denn da nicht?


----------



## JimboJT (4. Mai 2008)

Danke für deine Antwort.
Dein geposteter Quellcode hat bei mir auch nicht auf Anhieb funktioniert. Habe ihn ein bisschen verändert.
Habe aber noch immer 2 Compilerfehler.

(1) 
	
	
	



```
arr_data_length[i] = test[i].GetLength();
```
 (In der Zeile meckert er das links von GetLength() keine Klasse/Struktur/Union befindet. test[i] ist bei mir nur nen Array das ich so initialisiert habe -> int test[640])

(2) 
	
	
	



```
arr_data_value[i] = test[i]; ('Operator =' ist mehrdeutig
```
        c:\programme\microsoft visual studio 9.0\vc\atlmfc\include\cstringt.h(1066): kann 'ATL::CStringT<BaseType,StringTraits> &ATL::CStringT<BaseType,StringTraits>:perator =(wchar_t)' sein
        with
        [
            BaseType=char,
            StringTraits=StrTraitMFC<char>
        ]
        c:\programme\microsoft visual studio 9.0\vc\atlmfc\include\cstringt.h(1059): oder "ATL::CStringT<BaseType,StringTraits> &ATL::CStringT<BaseType,StringTraits>:perator =(char)"
        with
        [
            BaseType=char,
            StringTraits=StrTraitMFC<char>
        ]
        bei Anpassung der Argumentliste '(CString, int)')


```
const std::size_t count_elements(640);

	CString arr_data_value[count_elements];
	int arr_data_length [count_elements]; 
	
	// Dialog zum Speichern einer Datei
	CFileDialog fileDlg(FALSE, TEXT(".txt"), NULL, 0, TEXT("Textfile (*.txt)|*.txt|All Files (*.*)|*.*||"));
	fileDlg.DoModal();

	CString pfad = fileDlg.GetPathName ();
	//const CString file_path(dlg_filename.GetPathName()); 
	
	// Dies ist der String der gepeichert wird
	for (std::size_t i(0); i < count_elements; ++i)
	{    
		arr_data_value[i] = test[i];    
		arr_data_length[i] = test[i].GetLength();
	} 
	
	// Öffnen der Datei zum Schreiben
	CFile file;
	file.Open (fileDlg.GetPathName(), CFile::modeCreate | CFile::modeWrite); 
	
	// Inhalt des Strings in Datei schreiben
	
	for (std::size_t i(0);i < count_elements; ++i)
	{   
		file.Write(arr_data_value[i], sizeof(arr_data_length[i]));   
		file.Write(arr_data_value[i], arr_data_length[i] * sizeof(TCHAR));
	}
	// Schliessen der Datei
	file.Close ();
```

Naja das sind meine beiden Fehlerbilder. Hoffe du kannst mir dabei helfen, bin ja nicht wirklich der C++ Programmierer.
Danke.


----------



## JimboJT (4. Mai 2008)

Habe gerade meinen Fehler selber entdeckt ... Danke für deine Hilfe. Vielleicht kannst du ja mir trotzdem nochmal helfen, wie kann ich die Anweisung geben, dass die Zahlen untereinander geschrieben werden?


----------



## devDevil (4. Mai 2008)

Du schreibst binary ... da garnicht  Untereinander schreiben gibt es garnicht. Es ist nur, das Texteditoren das Zeichen  '\n' als neue Zeile interpretieren und es als solche anzeigen ...


----------



## JimboJT (5. Mai 2008)

So, habe jetzt meinen Quelltext für das Speichern soweit umgeschrieben und es t.


```
// Dialog zum Speichern einer Datei 
CFileDialog fileDlg(FALSE, ".txt", NULL, 0, "Textfile (*.txt)|*.txt|All Files (*.*)|*.*||"); 

fileDlg.DoModal();
CString pfad = fileDlg.GetPathName (); 
fstream datei;

datei.open(pfad, ios::out);
for(i = 0; i < 640; i++)
{
	datei << test[i] << endl;
}
datei.close();
```

So das untere ist meine Funktion für das Laden der Datei. Leider ließt er keine Werte in den Buffer. In der Datei sind aber Int Zahlen abgelegt, so dass er wenigstens etwas laden müsste. Weißt du da vllt. eine Antwort?

```
// Dialog zum Laden einer Datei 
CFileDialog fileDlg(TRUE, ".txt", NULL, 0, "Textfile (*.txt)|*.txt|All Files (*.*)|*.*||"); 

fileDlg.DoModal();
CString pfad = fileDlg.GetPathName (); 
ifstream datei(pfad);

//datei.open(pfad, ios::in);
std::string buffer[640];

for(i = 0; i < 640; i++)
{
	getline(datei, buffer[i]);
}
datei.close();
```


----------



## devDevil (5. Mai 2008)

Man junge du mixt da mehr als dir lieb sein kann 

Entscheide dich. Entweder du abstrahierst deine Grafik und Datenebene, dann nutzt du für deine Grafikebene von mir aus MFC und für den Rest pur C++, oder du nimmst nur MFC bzw. nur C++.

Du willst also einen Array da speichern, richtig?

```
CFileDialog dialog_filename(FALSE, TEXT(".txt"), NULL, 0, TEXT("Textfile (*.txt)|*.txt|All Files (*.*)|*.*||"));
dialog_filename.DoModal();

std::ofstream file_stream(dialog_filename.GetPathName().GetBuffer());
if (!file_stream) { MessageBox(TEXT("Datei konnte nicht geöffnet werden!"), 0); return FALSE; }

std::copy(test, test + 640, std::ostream_iterator<int>(file_stream, "|"));
```
 fertig ist es.


----------



## JimboJT (5. Mai 2008)

Da ich nebenbei noch auflege ist mixen ganz gut.
Das Abspeichern ist ja auch kein Problem mehr, jetzt haperts beim Auslesen.

Gruss


----------



## devDevil (5. Mai 2008)

Na da unterscheidet sich dein Code von meinem ... ich trenne alle Zahlen einfach per | ... mach es bsw. durch Leerzeichen odg. Leerzeichen wird vom Stream geskippt ... dann wäre das so:

*Speichern*

```
CFileDialog dialog_filename(FALSE, TEXT(".txt"), NULL, 0, TEXT("Textfile (*.txt)|*.txt|All Files (*.*)|*.*||"));

dialog_filename.DoModal();

std::ofstream file_stream(dialog_filename.GetPathName().GetBuffer());
if (!file_stream) { MessageBox(TEXT("Datei konnte nicht geöffnet werden!"), 0); return FALSE; }

std::copy(test, test + 640, std::ostream_iterator<int>(file_stream, " "));
```

*Laden*

```
CFileDialog dialog_filename(TRUE, TEXT(".txt"), NULL, 0, TEXT("Textfile (*.txt)|*.txt|All Files (*.*)|*.*||"));

dialog_filename.DoModal();

std::ifstream file_stream(dialog_filename.GetPathName().GetBuffer());
if (!file_stream) { MessageBox(TEXT("Datei konnte nicht geöffnet werden!"), 0); return FALSE; }

std::copy(std::istream_iterator<int>(file_stream), std::istream_iterator<int>(), test);
```


----------



## JimboJT (6. Mai 2008)

Hi,

so habe mal deinen Code auch ausprobiert. Die Speicherung funktioniert bei mir einwandfrei nur das Laden läuft bei mir nicht. Ich kriege in mein Integer Array test nicht die Werte aus der Txt File geladen bzw. es steht nachher nichts drin.

Kannst du mir vllt. die Zeile näher erläutern? Warum brauche ich bei der Ansteuerung von einem Array nicht die Indexe []?


```
std::copy(std::istream_iterator<int>(file_stream), std::istream_iterator<int>(), test);
```
Danke für deine Mithilfe!

Gruss


----------



## devDevil (6. Mai 2008)

Hmm sollte aber ... 

Es wird nen Anfangs und Enditerator als Parameter übergeben und der Anfang des Zielorts.

Nimm notfalls std::vector.


----------



## JimboJT (7. Mai 2008)

So, habe die Funktion nochmal getestet aber mit nem neu erstellten Array. Jetzt läuft es ohne Probleme.
Danke dir.


----------

