Cin.Getline nur Zahlen erlauben



  • Hallo zusammen
    Bin neu hier.
    Bin der Sven, 20 Jahre alt und befinde mich mitten im Studium.
    Haben da jetzt auch C++ Programmierung. Komme auch soweit zu recht.
    Nur hänge ich zur Zeit bei einer Aufgabe. Die Aufgabenstellung lautet:

    Schreiben Sie ein Programm, das nach einer Zeichenkette fragt und diese dann in einen long int-Wert umwandelt und diesen zum Schluß ausgibt. Verwenden Sie dazu wieder keine fertige Funktion,sondern programmieren dies selber.
    -Ändern Sie Ihr Programm so ab, dass man nun auch Vorzeichen (positiv und negativ) vor die Zahl schreiben kann.
    -Achten Sie darauf, dass Fehlermeldungen ausgegeben werden, wenn irgendetwas falsch ist oder wenn die Zahl zu groß für ein long int ist.

    Das habe ich soweit auch verstanden. Nur bekomme ich nicht auf Teufel komm raus, wie man auslesen kann, ob Zahlen und Buchstaben eingegeben wurden.

    Hier ist mal mein Code:

    #include <iostream>
    #include <string>
    using namespace std;
    int i,a,d;
    int vorzeichen,isstart;
    
    int main() {
    
    long int wert = 0, len;
    char kette [81] ;
    cout<< "Bitte geben Sie eine Zahl ein " <<endl;
    
    cin.getline (kette,81);
    len = strlen (kette);
    isstart = 0; vorzeichen = 1;
    
    	if (kette[0]== '+')
    
    		isstart = 1;
    
    			if (kette[0]== '-'){
    
    				isstart = 1;
    
    				vorzeichen = -1;
    
    			}
    
    				if (strlen(kette) > 11 ){
    					cout << "Bitte geben Sie eine kleinere Zahl ein"<<endl;
    					cin.get();
    				}
    
    				if (*kette >= 65){
    
    					cout << "Bitte geben Sie nur Zahlen ein"<<endl;
    					cin.get();
    
    				}
    
    for (int i = isstart; i < len; i++)
    {
    	wert = wert*10 + (kette[i]-48);
    }
    
    	wert= wert*vorzeichen;
    
    	cout<< wert;
    
    	return 0;
    }
    


  • Schau dir mal die Funktion isdigt an.

    Statt der Zahlenwerte solltest du die Zeichendarstellung benutzen, also z.B.

    wert = wert*10 + (kette[i]-'0');
    

    Und jetzt kannst du dir auch überlegen, wie man die isdigit-Funktion auch selber schreiben kann (wenn man weiß, daß die Ziffern 0 - 9 aufeinanderfolgend sind - dies ist vom C++-Standard garantiert).

    Und ändere mal die Einrückung bei deinem Code passend - das ist so kaum zu lesen.



  • Danke mal für den Link. Schau mir den morgen mal und arbeite mich rein.
    Im Grunde funktioniert bei mir ja schon alles.
    Habe die Idee gehabt beim letzen if , dass der Zeiger ja einen Wert annimmt. Und wenn dieser größer als 65 ist (dort beginnt in der ASCII-Tabelle die Buchstaben) wird geschrieben, dass keine Zahl eingeben wurde.
    Das Problem aber ist, dass wenn man "urffeichhhudf" eingibt, erkannt wird, dass Buchstaben eingegeben wurden. Wenn man aber z.B. "3efsdfe" eingibt, werden nur Zahlen als Resultat ausgegeben.
    Mal schauen ob das durch die isdigit Methode behoben bekomme.
    Mit freundlichen Grüßen



  • Meistens, wenn ich nen plain old array seh, les ich den Code nicht mehr.



  • rewrew schrieb:

    Meistens, wenn ich nen plain old array seh, les ich den Code nicht mehr.

    Sorry. Abern so haben wir es in der Uni gelernt. Wie würdest du es machen?



  • std::string



  • Swordfish schrieb:

    std::string

    Ist halt eine Frage der Vorgabe: Aus der Aufgabenbeschreibung handelt es sich um die Erweiterung einer vorherigen Lösung und fertige Funktionen dürfen nicht verwendet werden. Ergo soll das vermutlich so sein wie es ist.

    Übrigens "...Vorzeichen schreiben kann..." bedeutet, dass nicht unbedingt ein "+" vorne dran steht.



  • ja ne, aber im OP <string> einbinden 😡



  • So habe mich heute wieder ein wenig dran gehockt und versucht mich wieder einzuarbeiten.
    Bin auch ein bisschen weiter gekommen.

    if (kette[0] >= 65||kette[1] >= 65){
    								cout << "Bitte geben Sie nur Zahlen ein"<<endl;
    								cin.get();
    								}
    

    Nur müsste ich das für 82 Stellen machen.
    Gibt es da nicht ne andere Variante?
    Mit Schleifen habe ich es irgendwie nicht zum laufen gebracht 😕
    Hat vlt einer ne Idee?



  • So zB. prüfst du, ob die Zeichenkette nur Ziffern enthält:

    bool IsStrNum(const char* str) // für null-terminierte C-style strings
    {
    	while(*str && *str >= 48 && *str <= 57 && ++str);
    	return !*str;
    }
    

    Zugegeben, etwas kompakt, aber versuch mal's zu verstehen 😉
    Achtung: Bei einer leeren Zeichenkette kommt auch true zurück, aber das sollte egal sein.



  • Wie soll ich auf Ideen kommen, ohne überhaupt den Code zu sehen, der nicht läuft.



  • Hä?
    Der steht doch ganz oben eigentlich.
    Aber ich ich poste ihn dann halt nochmal:

    #include <iostream>
    #include <string>
    using namespace std;
    int i,a,d,z;
    int vorzeichen,isstart;
    
    int main() {
    
    long int wert = 0, len;
    char kette [81] ;
    
    cout<< "Bitte geben Sie eine Zahl ein " <<endl;
    
    cin.getline (kette,81);
    len = strlen (kette);
    isstart = 0; vorzeichen = 1;
    
    	if (kette[0]== '+')
    
    		isstart = 1;
    
    			if (kette[0]== '-'){
    
    				isstart = 1;
    
    				vorzeichen = -1;
    				}
    
    			if (kette[0] <= 65||kette[1] >= 65||kette[2] >= 65||kette[3] >= 65||kette[4] >= 65||kette[5] >= 65||kette[6] >= 65||kette[7] >= 65||kette[8] >= 65||kette[9] >= 65||kette[10] >= 65||kette[11] >= 65||kette[12] >= 65){
    											cout << "Bitte geben Sie nur Zahlen ein"<<endl;
    											cin.get();
    											}
    
    					if (strlen(kette) > 11 ){
    						cout << "Bitte geben Sie eine kleinere Zahl ein"<<endl;
    						cin.get();
    						}
    
    			for (int i = isstart; i < len; i++)
    				{
    					wert = wert*10 + (kette[i]-'0');
    				}
    
    	wert= wert*vorzeichen;
    
    	cout<< wert;
    
    	return 0;
    }
    

    Das ist jetzt mein aktueller Stand.



  • Schön, dass du meinen Beitrag einfach ignorierst.
    Oder kapierst du's einfach nicht? Wär ja nicht schlimm, aber sag's doch 🙄



  • Oh. Entschuldigung habe die Antwort überhaupt nicht gesehen 😮
    Sorry. Aber jetzt beim anschauen erkenne ich auch nur Bahnhof.
    Zum einen weiß ich nicht was es sich mit dem bool Klasse auf sich hat.
    Da hatten wir in der Uni noch nicht und wir dürfen nur das verwenden was wir schon behandelt haben.

    Zu meinem geposteten Ansatz:
    Das komische ist, dass für große Zahlen dieser funktioniert.
    Nur für Zahlen wie zum Beispiel "12" erkennt das Programm diese als einen Buchstaben. Woran liegt denn das?
    Mit freundlichen Grüßen



  • Wenn du eigene Funktionen schreiben sollst, brauchst du oft auch nen Rückgabewert.
    bool ist da nur logisch, das steht einfach für true/1 oder false/0.

    Grundlagen lernen bitte, das dauert nicht lange. Außer es ist die erste Sprache 😃

    Ich denke nicht, dass du das "<=" so willst?

    if (kette[0] <= 65||kette[1] >= 65||

    Außerdem ist es völlig schwachsinnig, das nicht in einer Schleife zu machen.



  • Das ist ja das Problem.
    Ist meine erste Programmiersprache.
    Das mit dem Größerzeichen hatte ich falsch kopiert gehabt.
    Im richtigen Code steht es richtig. Aber ich frage noch immer warum dies für kleine Zahlen nicht geht, sondern nur für große Zahlen diese als Zahlen erkannt werden. Ich weiß auch dass es nicht die schönste Lösung ist, aber ich möchte erst mal meinen Fehler bei dieser verstehen um im nächsten Schritt döse effizienter zu machen.
    Mit freundlichen Grüßen



  • Wie kann man falsch kopieren 😃

    Dann sag mal, bei welchem Input welcher Output kommt.



  • Ich hatte den Code kopiert gehabt als ich noch Sachen ausprobierte und da habe ich wohl vergessen gehabt, das Zeichen zu ändern. Aber egal 🙂

    Jetzt sieht die Zeile so aus

    if (48 <= kette[0] >= 65 || kette[1] >= 65 || kette[2]>= 65 || kette[3]>= 65 || kette[4]>= 65 || kette[5]>= 65 || kette[6]>= 65 || kette[7]>= 65 || kette[8]>= 65 || kette[9]>= 65 || kette[10]>= 65 || kette[11]>= 65 ){
    
                        cout << "Bitte geben Sie nur Zahlen ein"<<endl;
                        cin.get();
    

    Wenn ich jetzt eine 12 eingebe und Enter drücke, schreibt es dass es eine Zahl wäre. Drücke ich dagegen nochmal Enter kommt die 12.
    Wenn ich fünfstellige Zahlen eingebe, erkennt es diese als Zahlen. Alle drunter als Nichtzahlen.
    Insgesamt wenn ich fünfstellige Zeichen eingebe funktioniert die Ausgabe erst richtig.
    Mit freundlichen Grüßen



  • Dein Test character >= 65 überprüft nicht, ob character eine Ziffer ist. Wenn wir mal von ASCII ausgehen, haben Zeichen wie das Ausrufezeichen, runde Klammern, Kleiner- und Größerzeichen, Plus, Minus, Mal und Geteilt alle Werte kleiner als 65.

    Daher: teste, ob character im gewünschten Bereich liegt, d.h. if (character >= '0' && character <= '9') { gültig; } else { ungültig; }

    Wenn du die Zeichen '0' und '9' nimmst, ist es gleich viel besser lesbar als mit irgendwelchen ASCII-Codes.

    Das ganze solltest du dann in eine Funktion schreiben, die du für jedes Zeichen aufrufst. Du könntest sie z.B. isDigit nennen.

    (ich gehe mal davon aus, dass du das selber machen sollst - ansonsten schau mal auf http://www.cplusplus.com/reference/cctype/)



  • Jajobe schrieb:

    if (48 <= kette[0] >= 65 || ...
    

    Das ist fatal. Dadurch wird erst dieser Ausdruck

    48 <= kette[0]
    

    ausgewertet und dann dieser

    [Ergebnis] >= 65
    

Anmelden zum Antworten