C++ suche alternative zu std::cout für schöneres Interface

foggy80

Lt. Commander
Registriert
Juli 2008
Beiträge
1.034
Hallo,
ich übe momantan an einem c++ Konsolenprogramm. Die Benutzereingabe wird so realisiert:
Code:
	char c = 'z';
	while (c != '0') {

		std::cout << "Bitte machen Sie eine Eingabe:\n";
		std::cout << "0: Programm beenden\n";
		std::cout << "1: Komplette Liste ausgeben\n";
		std::cout << "2: Neuen Eintrag erstellen\n";
		std::cout << "\nIhre Eingabe: ";		

		std::cin >> c;

		switch(c) {
			case '0': break;
			case '1': root.printpurchaselist(); break;
			case '2': neupurchase(root); break;
			case '3': purchasespeichern(root); break;
		}
	}
	return 0;
Wenn eine Eingabe erwartet wird, kann man ein Zeichen eintippen und muss dann mit Enter bestätigen. Wenn man allerdings kein Zeichen eingibt und trotzdem Enter drückt, springt der Cursor in der Konsole an den Anfang der nächsten Zeile. Ich möchte aber, dass wenn kein Zeichen eingegeben wird, nochmal "\nIhre Eingabe: " ausgegeben wird, damit man ein schöneres Interface bekommt. Es soll also ähnlich sein wie in der windows cmd, wenn man dort Enter drückt ohne etwas eingegeben zu haben, wird nochmal der Pfad ausgegeben in dem man sich momentan befindet. Bei mir soll es eben nicht der Pfad sein, sondern "\nIhre Eingabe: ".

Ist sowas möglich?

Vielen Dank für eure Hilfe,
foggy
 
Zuletzt bearbeitet:
Indem du einfach in der Switch-Anweisung ein default-Eintrag machst, wo du ein Flag auf true setzt und dieses Flag in der Eintrittbedingung abfragst.

Code:
char c = 'z';
int flag = 0;
while (!flag && (c != '0')) {
  flag = 0;
  std::cout << "Bitte machen Sie eine Eingabe:\n";
  std::cout << "0: Programm beenden\n";
  std::cout << "1: Komplette Liste ausgeben\n";
  std::cout << "2: Neuen Eintrag erstellen\n";
  std::cout << "\nIhre Eingabe: ";		

  std::cin >> c;

  switch(c) 
  {
    case '0': break;
    case '1': root.printpurchaselist(); break;
    case '2': neupurchase(root); break;
    case '3': purchasespeichern(root); break;
    default: flag = 1;
  }
}
return 0;

So sollte es gehen.

edit:
Achso, du wolltest nur, dass "ihre Eingabe" erscheint.

Code:
char c = 'z';
int flag = 0;

std::cout << "Bitte machen Sie eine Eingabe:\n";
std::cout << "0: Programm beenden\n";
std::cout << "1: Komplette Liste ausgeben\n";
std::cout << "2: Neuen Eintrag erstellen\n";
  
while (!flag)
{
  flag = 0;
  std::cout << "\nIhre Eingabe: ";	
  std::cin >> c;	

  switch(c) 
  {
    case '0': break;
    case '1': root.printpurchaselist(); break;
    case '2': neupurchase(root); break;
    case '3': purchasespeichern(root); break;
    default: flag = 1;
  }
}

return 0;

Eine Konsole macht nämlich noch was anderes. Eine Konsole befindet sich in einer Dauerschleife, die nur durch ein terminieren der Konsole gestoppt werden kann. wenn man dann nämlich Enter drückt, versucht die Konsole den Befehl "" auszuführen. Was letzendlich nichts ist und wieder in die Konsole zurückkehrt.
 
Zuletzt bearbeitet:
Beide deiner Lösungsvorschläge haben das Problem leider nicht lösen können: Wenn ich im Programm aufgefordert werde einen char einzugeben, allerdings keinen char eingebe aber trotzdem Enter drücke, springt der Cursor nach wie vor an den Anfang der nächsten Zeile, ohne dass "Ihre Eingabe" nochmals ausgegeben wird.

Wenn ich nämlich keinen char eingebe und trotzdem Enter drücke, bleibt das Programm im std::cin und erwartet weiterhin einen char. Deswegen denke ich nicht dass man den gewünschten Effekt mit std::cin erreichen kann.
 
Zuletzt bearbeitet:
So, hab den Teilcode jetzt fertig. Hatte noch ein Problem mit dem stdin Stream, immer wenn das zweite Mal putchar aufgerufen wurde, wurde noch das '\n' von der Eingabe zuvor eingelesen. Nun wird der stream nach jedem putchar durch fflush(stdin) geleert. Aber ich hab gehört dass fflush nicht sehr portabel ist, hat jemand vll eine besser Lösung des Problems?

Code:
	char c = 'z';

	while(c != '0') {
		std::cout << "Bitte machen Sie eine Eingabe:\n";
		std::cout << "0: Programm beenden\n";
		std::cout << "1: Komplette Liste ausgeben\n";
		std::cout << "2: Neuen Eintrag erstellen\n";
		
		while(c != '0') {
			std::cout << "Ihre Eingabe: ";		
			c = getchar();
			fflush(stdin);
		
			switch(c) {
				case '0': break;
				case '1': root.printpurchaselist(); break;
				case '2': /*neupurchase(root);*/ break;
				case '3': /*purchasespeichern(root);*/ break;
				case '\n': break;
				default: std::cout << "Keine gueltige Eingabe!" << std::endl;
			}

		}
	}
 
Hallo,

fflush(stdin) ist undefiniertes Verhalten. Der Standard sagt ausdrücklich, dass fflush nur für Ausgabestreams definiert ist. Sehr viele Compiler/Library-Hersteller haben aus Genervtheit von falschen Bugreports eine Funktionalität eingebaut, die etwas in der Art tut, was man erwarten würde.

Außerdem müssen stdin und std::cin dafür synchronisiert sein, damit das theoretisch gehen kann. (Du flusht stdin und erwartest, dass std::cin den gleichen Buffer benutzt)

Du solltest zuerst bedenken - die Standardeingabe muss nicht von der Tastatur sein. Und Linux-artigen OS ist es üblich, den Inhalt einer Datei an das Programm zu schicken - dann fällt dein Programm komplett auf die Nase.

Kurzum - dein Problem ist nicht mit Standard-C++ zuverlässig lösbar. Du brauchst hierfür Betriebssystem-spezifische Bibliotheksfunktionen, die das gewünschte tun. Dazu müsste man zuallererst mal wissen, unter welchem Betriebssystem du bist.

Gruß
 
Zurück
Oben