C++ Ausgabe Problem

AirForce

Lt. Junior Grade
Registriert
Okt. 2010
Beiträge
296
Schreibe ein Programm das eine Person Struktur einlesen soll und wieder ausgeben. Doch es will keine Ausgabe machen. Die Person Struktur die in der main() definiert wurde wird ohne Probleme Ausgeben nur was danach über den >> Operator eingelesen wird nicht ausgeben.

Code:
class Person
{
private:
	string name; 
	int age; 
public:
	Person(string n, int a):name(n), age(a) 
	{
		if(age < 0 || age > 150)
			error ("Alter ist ungueltige!");
		for(int i = 0;i<name.size();++i)
		switch(name[i])
	    {
		case ';': case ':': case '"': case '\'': case '[': case ']':
		case '*': case '&': case '^': case '%': case '$': case '#': 
		case '@': case '!':
			error ("Ungueltiger Name!");
	    }
	}
	Person() : name("Unbekannt"), age(0) {}
	 
	string name2() const { return name; }
	int age2() const { return age; }

	friend istream& operator>>(istream& is, Person& P);
};

Code:
istream& operator>>(istream& is, Person& P)
{
	cout << "Person und Alter eingeben" << endl;
	while (is>>P.name>>P.age)
	{
	if(P.age < 0 || P.age > 150)
		   error ("Alter ist ungueltige!\n");
	if(!is) return is;

	for(int i = 0;i<P.name.size();++i)
		switch(P.name[i])
	    {
		case ';': case ':': case '"': case '\'': case '[': case ']':
		case '*': case '&': case '^': case '%': case '$': case '#': 
		case '@': case '!':
			error ("Ungueltiger Name!");
	    }  
	}

	return is;
}

ostream& operator<<(ostream& os, Person& P)
{
	return os << P.name2() << " " << P.age2() << endl;		
}

int main()
try{
	Person P1("Goofy",63);
	cout << P1;

	vector <Person> ps;

	Person P;
	cin >> P; 
	ps.push_back(P);
        cout << P;

	keep_window_open();
}
catch (runtime_error e) {	
	cout << e.what() << '\n';
	keep_window_open("~");	
}
 
Was passiert stattdessen? Das Programm läuft normal durch, nur eben ohne daß die Ausgabe erscheint? Oder gibt es einen Absturz?
 
Das Programm läuft ohne Absturz. Nur will ich das die Ausgabe funktioniert und das funktioniert nicht. Später will ich auch die werte im vector auch ausgeben. Doch zuerst muss man denn Fehler bei der Ausgabe finden. Wie gesagt bei der main() definierten klasse wird eine Ausgabe gemacht. Wird was mit cin eingelesen wird keine Ausgabe gemacht. Und das ist das Problem.
 
Habe dein Programm eben mal mit dem Debugger laufen lassen. Dein >>-Operator zum Einlesen einer Person kommt bei mir nie aus der while-Schleife raus sondern fragt endlos nach neuen Eingaben. Wenn du eine gültige Eingabe bekommen hast, mußt du aus der while-Schleife auch mal wieder raushopsen.
Ergänzung ()

So gehts:

Code:
istream& operator>>(istream& is, Person& P)
{
	cout << "Person und Alter eingeben" << endl;
	while (is>>P.name>>P.age)
	{
		if(P.age < 0 || P.age > 150)
			error ("Alter ist ungueltige!\n");
		if(!is)
		{
			return is;
		}

		for(int i = 0;i<P.name.size();++i)
			switch(P.name[i])
		{
			case ';': case ':': case '"': case '\'': case '[': case ']':
			case '*': case '&': case '^': case '%': case '$': case '#':
			case '@': case '!':
				error ("Ungueltiger Name!");
		}

		break;
	}

	return is;
}
 
Zuletzt bearbeitet:
Und jetzt noch ein paar Anmerkungen:

Code:
catch (runtime_error e) { ...

Exceptions niemals per value sondern lieber per const reference fangen. Also

Code:
catch (const runtime_error &e) { ...

Sonst kannst du dir Probleme einhandeln, wenn mal eine Exception von einem von runtime_error abgeleiteten Typ geworfen wird (google mal nach "C++ slicing").


Außerdem, in deinem Operator << sollte das Person-Argument const sein.

Code:
ostream& operator<<(ostream& os, const Person& P)

Der Operator soll P ja schließlich nicht verändern können sondern es lediglich ausgeben.
 
Habe die Änderung gemacht. Jetzt wird eine Ausgabe gemacht, aber es springt aus der Schleife. Ich meine wurde ein guter wert eingelesen wird es Ausgeben und das Programm ist am ende angelangt. Es soll aber weiter nach werten Fragen bis eine ungültige Eingabe kommt. Danach kann es sich beenden. Das Problem ist folgendes ich habe zwar Ausgabe aber keine schleife mehr.
 
Dann mußt du eben in main() eine Schleife einbauen, die pro Schleifendurchlauf ein mal

1) Vom Benutzer eine Eingabe anfordert.
2) Die so befüllte Person auf dem Bildschirm ausgibt.
 
Das wurde geändert:
Code:
istream& operator>>(istream& is, Person& P)
{
	cout << "Person und Alter eingeben" << endl;

	is>>P.name>>P.age;
	if(P.age < 0 || P.age > 150)
		   error ("Alter ist ungueltige!\n");
	if(!is)
	{
	   return is;
	}
	for(int i = 0;i<P.name.size();++i)
		switch(P.name[i])
	    {
		case ';': case ':': case '"': case '\'': case '[': case ']':
		case '*': case '&': case '^': case '%': case '$': case '#': 
		case '@': case '!':
			error ("Ungueltiger Name!");
	    }  
	return is; 
}

Code:
int main()
try{
	Person P1("Goofy",63);
	cout << P1;

	vector <Person> ps;

	Person P;
	while(cin >> P)
        {
	ps.push_back(P);
        cout << P;
        }

	keep_window_open();
}
catch (const runtime_error e) {	
	cout << e.what() << '\n';
	keep_window_open("~");	
}

Schleife funktioniert jetzt ohne Probleme. Wenn ein ungültiger wert eingeben wird wird die Schleife verlassen.

Jetzt eine frage. Ich will die werte im vector ausgeben lassen. Und dafür will ich die Ausgabe operator anpassen. Soll ich dafür den vector global definieren oder kann ich es in der main() lassen?
 
Zuletzt bearbeitet:
AirForce schrieb:
Das wurde geändert:
Code:
istream& operator>>(istream& is, Person& P)
{
	cout << "Person und Alter eingeben" << endl;

	is>>P.name>>P.age;
	if(P.age < 0 || P.age > 150)
		   error ("Alter ist ungueltige!\n");
	if(!is)
	{
	   return is;
	}
	for(int i = 0;i<P.name.size();++i)
		switch(P.name[i])
	    {
		case ';': case ':': case '"': case '\'': case '[': case ']':
		case '*': case '&': case '^': case '%': case '$': case '#': 
		case '@': case '!':
			error ("Ungueltiger Name!");
	    }  
	return is; 
}

Code:
int main()
try{
	Person P1("Goofy",63);
	cout << P1;

	vector <Person> ps;

	Person P;
	while(cin >> P); 
	ps.push_back(P);
        cout << P;

	keep_window_open();
}
catch (const runtime_error e) {	
	cout << e.what() << '\n';
	keep_window_open("~");	
}

Schleife funktioniert jetzt ohne Probleme. Wenn ein ungültiger wert eingeben wird wird die Schleife verlassen.

Erklär mal, was diese Zeile tut, und du kommst von selbst drauf, wo das Problem liegt.

while(cin >> P);
 
while(cin>>P) liest ja de Person Struktur in einer Schleife ein. Damit es auch etwas Ausgeben wird muss man ja klammern setzten damit das Programm auch bis zur Ausgabe kommt. Ohne klammern ist das nur eine einlese Schleife.
Ergänzung ()

Eine Frage kann man die werte im vector nicht sortieren? Wenn ich das machen will bekomme ich Fehlermeldungen.
sort(ps.begin(),ps.end());
 
AirForce schrieb:
Ergänzung ()

Eine Frage kann man die werte im vector nicht sortieren? Wenn ich das machen will bekomme ich Fehlermeldungen.
sort(ps.begin(),ps.end());

Wenn du std::sort benutzen möchtest, mußt du ein Kriterium angeben, das zum Sortieren benutzt werden soll. Das kann eins von folgenden Dingen bedeuten:

  1. Du mußt eine Methode bool operator < ( const Person& lhs, const Person& rhs ); implementieren, die true liefert, wenn der linke Operand "kleiner" ist als der rechte.
  2. Du implementierst eine Funktion, die genau das gleiche tut wie der erwähnte Operator <, und gibst std::sort() als 3. Argument die Adresse dieser Funktion.

Außerdem solltest du dir angewöhnen, nicht immer gleich das Handtuch zu werfen, wenn mal was nicht gleich funktioniert. Hättest du z.B. mal ein wenig gegooglet und dir den einen oder anderen C++-Referenz-Eintrag zum Thema std::sort angeschaut (wie diesen hier http://www.cplusplus.com/reference/algorithm/sort/ ), wärst du da bestimmt auch selbst drauf gekommen.
 
Zuletzt bearbeitet:
Zurück
Oben