fehleingabe abfangen und string anzeigen obwohl Variable ein int ist? =-gelöst-=



  • Hallo Leute !
    Ich bin neu hier im Forum und auch in C++.Ich habe mich angemeldet weil ich gerne mehr über C++ lernen möchte. Es macht Spass und bietet viele Möglichkeiten wenn man es denn erstmal kann. Lange Rede kurzer Sinn. Hier meine Frage :

    Ich habe ein Programm geschrieben, was den user fragt wie alt er ist. Der user gibt seinen Alter an und je nachdem was er eingibt sollen halt verschiedene Antworten folgen. Das funktioniert soweit alles mit allen Verzweigungen, aber mir fällt einfach kein Ausdruck ein für eine If-Verzweigung wo abgefragt wird ob die Eingabe des users ein string ist. Und dieser soll natürlich auch ausgegeben werden können.

    Hier mal der Code damit ihr euch ein Bild machen könnt:

    #include <iostream>
    #include <conio.h>
    #include <Helper.h>
    
    using namespace std;
    int alter;
    
    char main (void)
    {
    Helper helper;
    helper.frage();
    cin >> alter;
    	if (alter == 0)
    	{
    		helper.antwort();
    	}
    	else
    	{
    		if (alter >= 1 && alter <= 14)
    		{
    			helper.antwort2();
    		}
    		else 
    		{
    			if (alter >= 15 && alter <= 19)
    			{
    				helper.antwort3();
    			}
    			else 
    			{
    				if (alter >= 20 && alter <= 30)
    				{
    					helper.antwort4();
    				}
    				else
    				{
    					if (alter > 30)
    					{
    						helper.antwort5();
    					}
    					if (alter < 0)
    					{
    	cout << "Negative Zahlen bei Altersangaben sind Quatsch^^" << endl;
    						_getch();
    						exit(1);
    					}
    				}
    			}
    		}
    	}
    
    }
    

    zur Orientierung : frage , antwort, antwort2 etc sind funktionen die ich in der Klasse Helper definiert habe. Sie geben einfach nur text aus und sorgen dafür, dass die Konsole sich nicht gleich schliesst wenn das Programm ausgeführt wurde.
    Ihr seht schon, ich habe einige Fälle von "alter" bereits durchgekaut. positive zahlen sind bearbeitet sowie negative und auch der fall = 0. Nun fehlt mir aber noch der Fall ob der user einen String eingibt. Und diesen würde ich dann auch ausgeben wollen.

    Kann mir da wer bitte helfen ? Wenn ihr mehr infos braucht , bekommt ihr die gern.


  • Mod

    Du kannst mit if (cin) prüfen, ob der Eingabestrom cin in einem Fehlerzustand ist oder nicht. So ein Fehlerzustand tritt beispielsweise ein, wenn eben eine Zeichenkette eingegeben wurde, obwohl eine Zahl eingegeben wurde. Du kannst sogar gleich if (cin >> alter) schreiben, da die ganzen Eingabeaktionen immer den Stream selber als Rückgabewert haben.

    Falls der Stream in einem Fehlerzustand ist, willst du vermutlich mittels clear() die Fehlerflags zurücksetzen (sonst schlagen alle weiteren Aktionen auch fehl) und die Zeichenkette ist dann natürlich auch noch imemr im Stream (konnte ja nicht gelesen werden), du willst sie vermutlich mit ignore überspringen.



  • Jo das habe ich auch schon in meinem Buch gelesen. Damit deckt man dann aber nur Die Abfrage ab. Und das noch nichtmal so wie es gemacht werden soll.
    in dem folgenden Beispiel gibt er dann in die Konsole einen seltsamen Ganzzahlwert an obwohl er ja auch die Zeichenkette ausgeben soll wenn denn eine eingegeben wird. Ich weiss auch, dass das wohl am Datentyp int liegt. Nur es muss doch auch eine Möglichkeit geben, auch Zeichenketten ausgeben zu lassen, selbst wenn die Variable vom Datentyp "int" ist.

    if ( cin >> alter)
    {
    cout << "du hast " << alter << " bei einer Altersangabe eingegeben..." << endl;
    _getch();
    exit(1);
    }
    

    Die Möglichkeit mit dem Überspringen und clearen der Eingabe kannte ich noch nicht. Aber er soll erstmal nur in der Lage sein die Zeichenkette zu erkennen und auszugeben.
    Ich hatte über eine Typumwandlung nachgedacht, die in der richtigen if-Verzweigung stattfinden soll. Aber das hatte auch nicht funktioniert. Ich bin mir sicher, dass die Syntax dazu stimmen sollte:

    if ( !(alter < 0) && !(alter > 0) && !(alter == 0) )
    {
     string s = static_cast<string>(alter);
     cout << s << " ist eine falsche Eingabe!" << endl;
    }
    

    aber evt ist das ja auch der falsche denkansatz. Ich bin echt ratlos



  • Wenn du einen int einliest, wird die Variable entweder auf den eingegebenen Wert gesetzt (immer eine Zahl) oder uninitialisiert gelassen (=zufälliger, seltsamer Ganzzahlwert).

    Entweder liest du eine Zeichenkette ein (also mit einer string-Variable) oder eine Zahl (int-Variable), wenn du einen string annehmen willst und in bestimmten Fällen in einen int umwandeln, brauchst du schon etwas mehr C++-Kenntnisse. Ich würde an deiner Stelle zuerst einfachere Sachen lernen.



  • Ergänzung: Wenn der Nutzer nichts sinnvolles eingegeben hat, bleibt iese Eingabe im Stream drin stehen - die wird zwar üblicherweise ignoriert, aber natürlich kannst du sie auch auswerten:

    if(cin>>alter)
    {
      ...
    }
    else
    {
      cin.clear();
      string input;
      getline(cin,input);
      cout<<"\""<<input<<"\" ist keine gültige Eingabe!!!"<<endl;
      ...
    }
    

    (btw, deine letzte if()-Abfrage ist komplett sinnfrei)



  • Zodiac Uchiha schrieb:

    #include <iostream>
    #include <conio.h>
    

    Hieraus entnehme ich, dass du dich noch nicht zwischen C++ und C und zwischen Standard und Nichtstandard entschieden hast.

    Zodiac Uchiha schrieb:

    char main (void)
    

    Das hier ist definitiv falsch.

    Lies am besten erst alles als String ein und mache deine Fallunterscheidung dann anschließend, indem du den String entsprechend auswertest.



  • #include <conio.h>
    

    habe ich nur inkludiert, weil ich in einen tutorialvideo gesehen habe, dass man

    _getch();
    

    verwendet um die Konsole davon abzuhalten sich selber sofort nach Ausführung des Programms zu schliessen. Ich möchte ganz klar mit C++ arbeiten. Ich möchte so wenig von C wie möglich mitnehmen, da ich gelesen habe, dass so manche Sachen sicherer laufen die in C++ standardisiert wurden.

    und ja. Das mit der Main methode habe ich befürchtet. Ich denke mal da würde man besser sowas wie

    void main () {}
    

    schreiben oder ?

    In meine letzte if abfrage da oben sollte noch ein cout hinein wo s wiedergegeben werden sollte.

    Der else part von CStoll ist sehr interessant. Ich werde mich mal damit befassen und das ausprobieren. Sobald das Ergebnis dann richtig ist, werde ich diesen Post editieren (oder einen neuen schreiben zur Benachrichtigung falls jemand noch einen Beitrag schreibt) und den Thread als gelöst markieren.
    Danke euch erstmal für all die Hilfe.



  • Zodiac Uchiha schrieb:

    weil ich in einen tutorialvideo gesehen habe, dass man _getch(); verwendet um die Konsole davon abzuhalten sich selber sofort nach Ausführung des Programms zu schliessen.

    Kauf dir ein Buch und ignoriere die Tutorialvideos, so lernst du nie C++.

    Und nein, es heisst int main() { } .



  • Zodiac Uchiha schrieb:

    Ich möchte ganz klar mit C++ arbeiten. Ich möchte so wenig von C wie möglich mitnehmen, da ich gelesen habe, dass so manche Sachen sicherer laufen die in C++ standardisiert wurden.

    C Programme gemäß C Standard sind genauso "sicher" wie C++ Programme gemäß C++ Standard (vorausgesetzt, dass der jeweilige Compiler den jeweiligen Standard unterstützt und der Programmierer in der Lage ist, den Compiler entsprechend zu bedienen).
    Oftmals werden aber C Konstrukte/Bibliotheksfunktionen innerhalb von C++ Programmen verwendet, und da wird es dann schwierig, insbesondere für Anfänger.
    conio.h und Konsorten sind jedenfalls weder irgendein C++ noch irgendein C Standard und für deinen Zweck reicht, wie ich sehen kann, auch die Zumutung an den Anwender, <ENTER> statt irgendeiner Taste zu drücken (und somit ohne getch auszukommen).



  • verstehe...Sicher, Enter würde natürlich auch reichen. aber wie mache ich das denn ?
    ausser

    _getch();
    

    kenne ich nur

    system("Pause");
    

    und selbst damit braucht man nur irgendeine taste drücken. das problem ist ja, dass sich die Konsole zu schnell nach dem Programm selbst schliesst, sodass man nicht die Gelegenheit hat sich alles nochmal anzuschauen. zumindest dann wenn man nicht solche Befehle verwendet.

    Aber ich entscheide mich dann trotzdem für C++. In dem Buch was ich habe wird tollerweise immer dabei gesagt, wenn es sich um Elemente von C handelt und dann sofort die C++ variante/neuerung mitbeschrieben.

    Edit : Der Fall ist gelöst. Dank CStolls Beitrag ist der Groschen dann gefallen.
    Ich werde mich noch etwas mit dem entscheidenen Part beschäftigen damit ich verstehe wie er genau funktioniert, sodass ich ihn auch woanders anwenden kann.
    Aber auch die anderen Beitrage der Member hier waren sehr hilfreich und lehrreich.
    Vielen dank nochmal.



  • std::cin.get();


Anmelden zum Antworten