C++ Kontenverwaltung

Bismark36

Newbie
Registriert
März 2008
Beiträge
3
Hi,

ich habe ein Problem und zwar mit dem Speichern und Laden.

Ich habe die nötigen Codes geschrieben, damit die Daten die ich während des laufenden Programms eingebe, gespeichert und beim öffnen des Programms wieder zu Verfügung stehen sollen. Ich habe nur den relevanten teil des Programms ins Thread kopiert, da es sehr groß ist.

Ich habe die Stellen Markiert



Code:
#include <conio.h>
#include <iostream>
#include <fstream>
#include <string>
#include "conioex.h"


using namespace std;



struct konto				//Def. Struckt
{
	string name;
	int kontonr;
	float kbetrag;
};

const int anz = 10;
konto liste[anz];

void kontoalg (konto liste[anz]);
void eazahl (konto liste[anz]);
void ausgeben (konto liste[anz]);
//int andern (konto liste[anz]);
//int loschen (konto liste[anz]);




int main()													//Anfang Hauptprogramm
{
char wahl;

textcolor(GREEN);
textbackground(YELLOW);
	do
	{
	system ("cls");
		gotoxy(29,10);
		cout<<"#### M E N U E ####"<<endl<<endl;
		gotoxy(29,12);
		cout<<"<1> Konto Anlegen"<<endl;
		gotoxy(29,13);
		cout<<"<2> Ein-/Auszahlung"<<endl;
		gotoxy(29,14);
		cout<<"<3> Daten Ausgeben"<<endl;
		gotoxy(29,15);
		cout<<"<4> Daten aendern"<<endl;
		gotoxy(29,16);
		cout<<"<5> Konto Loeschen"<<endl;
		gotoxy(29,17);
		cout<<"<#> Programm beenden"<<endl;
		gotoxy(43,19);
		cout<<"Ihre Wahl ==> ";
		cin>>wahl;


		switch (wahl)
		{
		case '1': kontoalg (liste);break;
	        case '2': eazahl (liste);break;
		case '3': ausgeben (liste);break;
		}
	}
	while(wahl != '#');

getch();

return 0;
}																				//Ende des Programms


void kontoalg(konto liste[anz])								
{
	char antwort;
	int zae=0, z=0;
	bool merker;


  
	do
	{
	system ("cls");
	gotoxy(29,10);
	cout<<"## KONTO ANLEGEN ##"<<endl<<endl;
	gotoxy(29,12);
	cout<<"Nachname: ";
	cin>>liste[zae].name;
	gotoxy(29,13);
	cout<<"Kontonr.: ";
	cin>>liste[zae].kontonr;
	gotoxy(29,14);
	cout<<"Kontostand: ";
	cin>>liste[zae].kbetrag;

	[COLOR="Red"]ofstream dataus;                                                    //Anfang Speichern
	dataus.open("konten.txt", ios::out);
	
	for(int y=0;y <anz;y++)
	{
		dataus<<liste[y].name<<" ";
		dataus<<liste[y].kontonr<<" ";
		dataus<<liste[y].kbetrag<<endl;
	}
	dataus.close();                                                     //Ende Speichern[/COLOR]

[COLOR="Green"]	ifstream datin;                                                      //Anfang Laden
	datin.open("konten.txt", ios::in);
	
	for(int y=0;!datin.eof();y++)
	{
	datin>>liste[y].name<<" ";
	datin>>liste[y].kontonr<<" ";
	datin>>liste[y].kbetrag<<endl;
	}
	datin.close();                                                      //Ende Laden[/COLOR]


	zae++;
	system ("cls");
	gotoxy(25,13);
	cout<<"Noch ein Konto anlegen? -j,J/n,N";
	cin>>antwort;


	}
	while(antwort == 'j' || antwort == 'J' && zae < 10 );

}


Der Compiler zeigt folgenden Fehler an:

Fehler 83 error C2784: "std::basic_ostream<_Elem,_Traits> &std:: operator <<(std::basic_ostream<_Elem,_Traits> &,char)": template-Argument für "std::basic_ostream<_Elem,_Traits> &" konnte nicht von "std::basic_istream<_Elem,_Traits>" hergeleitet werden.

Womit ich nichts anfangen kann.

Ich Hoffe ihr könnt mir helfen
__________________
 
Zuletzt bearbeitet:
Ich hoffe mal ich vertue mich nicht, aber funktioniert das:

/*Der Operator >> ignoriert automatisch alle Leerzeichen und Zeilenumbrüche, deshalb solltest du sie nicht mit einlesen müssen.
Und warum schreibst du das nicht in schöne Klassen, dann kannst du es doch viel besser verwenden ;-) */
Code:
 for(int y=0;y <anz;y++)
	{
		dataus<<liste[y].name<<" ";
		dataus<<liste[y].kontonr<<" ";
		dataus<<liste[y].kbetrag<<endl;
	}
	dataus.close();                                                     //Ende Speichern

	ifstream datin;                                                      //Anfang Laden
	datin.open("konten.txt", ios::in);
	
	for(int y=0;!datin.eof();y++)
	{
	datin>>liste[y].name;
	datin>>liste[y].kontonr;
	datin>>liste[y].kbetragl;
	}
	datin.close();
 
@Spartaner117: Ob ofstream und ifstream jetzt getrennt oder gleich fstream macht funktional keinen Unterschied.
Für die Behandlung der Leerzeichen könntest du dir einen Funktor schreiben.
Ein weiteres Problem sehe ich noch, wenn Vor- und Nachname gespeichert werden sollen. Dann wäre vllt. doch eine CSV-Datei klüger.

Um meinen ersten Beitrag zu ergänzen:
Code:
datin>>liste[y].name<<" ";
datin>>liste[y].kontonr<<" ";
Das ist natürlich auch nicht richtig. Du hast ja hier einen string resp. int vor dir.
 
Zuletzt bearbeitet:
Das eigentliche Problem ist, dass du bei einem Eingabestream die Ausgabe-Operatoren << benutzt. Bei i(f)streams darfst du nur >> benutzen, bei o(f)streams nur <<.
Die hast du beim Lesen gemischt.

Außerdem macht ein datin >> " " keinen Sinn. "Lese aus der Datei einen C-Character-String und schreibe ihn in das konstante Literal " "". Das bedeutet das. Ich hoffe, du verstehst, dass das keinen Sinn macht.

Außerdem wurde auch schon gesagt, dass alle istreams beim Lesen per Default alle Leerzeichen und Zeilenumbrüche überlesen. Demnach darf auch in konto.name kein (!) Leerzeichen enthalten sein, sonst passieren komische Sachen.

Oh und fread/fwrite, das solltest du ganz schnell mal wieder streichen.

Außerdem kann die Leseroutine eine potenzielle Endlosschleife sein. Ein Test auf nur .eof() reicht niemals, du musst auch immer auf .fail() prüfen.
 
Zuletzt bearbeitet:
fread und fwrite ...

1. machen unformatierten I/O. Das ist oft nicht das was man erwartet, wenn man sich nicht genau darüber im Klaren ist, was es macht.

2. sind im Gegensatz zu den C++ IOstreams schwieriger zu bedienen und lassen sich leicht falsch bedienen und sind klassische Sicherheitslücken (buffer overrun), für deren Absicherung man schon ein eher solides Wissen braucht

3. schreiben die binäre Repräsentation eines Werts, für die Berücksichtigung der Semantik ist der Anwender zuständig; C++ IOstreams arbeiten dagegen auf Typen und kümmern sich selbst um die korrekte binäre Repräsentierung

4. sind nicht typsicher (überschneidet sich mit 3.)


C++ IOstreams sind außerdem durch die Möglichkeit, die operatoren << und >> zu überladen flexibel und typsicher erweiterbar. Und, sie arbeiten für den Anwender mit Typen, nicht mit Repräsentationen (siehe hierzu z.B. C++ Coding Standards (Sutter/Alexandrescu), Item 91).

Zugegebener Maßen sind sie ein wenig langsamer als ein nacktes fread/fwrite - aber solange man nicht I/O in Dimensionen betreibt, wo das wirklich zu Buche schlägt, sollte man auf solche Schein-Performance-Vorteile keinen Wert legen.

Reicht das? :)

Für jemanden der weiß, was er will, und erfahren ist, mögen fread/fwrite für manche Sachen in Frage kommen. Für Gehversuche in C++ (so sieht mir das Beispiel eher aus), ist IMHO unbedingt davon abzuraten.
 
Zuletzt bearbeitet:
Zurück
Oben