Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » C++ Eingabe überprüfen » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen C++ Eingabe überprüfen
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
romaen
Jungspund


Dabei seit: 18.03.2013
Beiträge: 15

C++ Eingabe überprüfen Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hallo Leute,

folgende Frage hätte ich:

Angenommen wir haben ein simples Prog. bei dem ich zu Beginn eine int Zahl einlesen möchte.

code:
1:
2:
int Eingabe;
cin >> Eingabe;


Wie kann ich, am besten mit einer einfachen if Funktion, überprüfen ob es sich bei der Eingabe um eine Zahl handelt?

mehr oder weniger in dem Sinn:
code:
1:
if (Eingabe != int) return 0;


So funktioniert es ja leider nicht.. ich hoffe Ihr könnt mir helfen smile

Grüße
Roman
27.05.2013 11:29 romaen ist offline Beiträge von romaen suchen Nehmen Sie romaen in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hallo,

ich denke man muss sich die Funktion selbst schreiben. Schau dir mal http://www.cplusplus.com/reference/cstdlib/strtol/ an. Ich nehme an, dass wenn die Eingabe keine Zahl ist oder nicht mit einer Zahl oder einem Whitespace vor einer Zahl beginnt, dann wird 0L zurückgegeben und endptr wird auf str gesetzt..

VG,

Karlito
27.05.2013 12:48 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
Airblader Airblader ist männlich
Doppel-As


Dabei seit: 03.03.2013
Beiträge: 138
Herkunft: München

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Wenn du eine Variable vom Typ int einliest, dann ist sie auch vom Typ int (oder macht C++ hier was anders?). Wenn der Benutzer etwas eingegeben hat, das nicht auf int gecastet werden kann, sollte es entspr. schiefgehen.

Man könnte also einfach ein Fehlverhalten abfangen (try..catch), oder aber man muss einen String einlesen und diesen dann überprüfen.

Edit: C++ macht tatsächlich was anderes. Dann meinen Beitrag einfach mal ignorieren…

__________________
The best thing about a boolean is that even if you're wrong, you're only off by a bit.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Airblader: 27.05.2013 15:43.

27.05.2013 15:39 Airblader ist offline Beiträge von Airblader suchen Nehmen Sie Airblader in Ihre Freundesliste auf
romaen
Jungspund


Dabei seit: 18.03.2013
Beiträge: 15

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Danke Karlito für die Antwort!
Aber auch danke an Airblader.. irren ist ja bekanntlich menschlich smile
27.05.2013 18:00 romaen ist offline Beiträge von romaen suchen Nehmen Sie romaen in Ihre Freundesliste auf
Airblader Airblader ist männlich
Doppel-As


Dabei seit: 03.03.2013
Beiträge: 138
Herkunft: München

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Wenn ich mir die Dokumentation zu strtol so anschaue, dann ist das für mich ebenso merkwürdiges Verhalten. Im Wesentlichen ist die Verwendung dann nämlich doch analog zu einem einfachen

code:
1:
2:
int eingabe;
cin >> eingabe;


Das wird Nummern korrekt erkennen, liefert im Fehlerfall aber einfach eine "0" (das ist kein gutes Verhalten).

Ich hatte nun erwartet, dass strtol hier ein besseres Verhalten zeigt und tatsächlich etwas Sinnvolles tut, wenn man keine gültige Zahl reinsteckt. Leider kommt da ja auch nur 0 (bzw. 0L) bei heraus.
Völlig analog sind beide Methoden dennoch nicht, für den Input "3a" gibt meine Variante zum Beispiel '3' zurück, strtol hingegen 0L. Bei "a3" liefern zum Beispiel beide 0 zurück.

Wie gesagt, das ist aber einfach kein schönes Verhalten, auch wenn es "sicher" ist (keine Exceptions wirft). Wie will man denn so abfangen, ob der User nun Unsinn oder eine 0 eingegeben hat?

Ob meine Variante jetzt C++-spezifisich irgendwelche Nachteile hat weiß ich aber natürlich nicht.

__________________
The best thing about a boolean is that even if you're wrong, you're only off by a bit.
27.05.2013 19:49 Airblader ist offline Beiträge von Airblader suchen Nehmen Sie Airblader in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hallo,

ich habe es nicht geprüft, aber ich glaube dass strtol versucht immer "Wortweise" Zahlen zu lesen. Gibt man keine Basis > 10 an, so ist 3a keine gültige Zahl. Somit wird zu recht 0L zurückgegeben.
Meine Vermutung ist weiterhin, dass man zusätzlich den Parameter endptr belegen muss. Ist der "zürückgegebene Wert" endptr nach Aufruf der Funktion gleich dem Zeiger auf den Anfang des Strings, so wurde keine Zahl gelesen und man kann so eindeutig den Fehlerfall feststellen.

Übersehe ich etwas?

VG,

Karlito
28.05.2013 02:04 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
Airblader Airblader ist männlich
Doppel-As


Dabei seit: 03.03.2013
Beiträge: 138
Herkunft: München

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Für mich ist das Konvertieren von "5foo" in "5" bei einer String-to-Integer-Funktion aber einfach kein korrektes Verhalten. "5foo" ist keine Zahl und sollte komplett abgelehnt werden – imho. smile

Eigentlich würde ich mir von einer solchen Funktion wünschen, dass sie nur und ausschließlich echte Zahlen akzeptiert (und nicht versucht, nach bestem Wissen eine Zahl draus zu machen) und alles andere mit einer Exception ablehnt (und nicht mit 0L).

__________________
The best thing about a boolean is that even if you're wrong, you're only off by a bit.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Airblader: 28.05.2013 13:17.

28.05.2013 13:16 Airblader ist offline Beiträge von Airblader suchen Nehmen Sie Airblader in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

IMHO ist C++ sehr stark performanceorientiert. Es gibt die Möglichkeit zu prüfen, ob eine Zahl eingegeben wurde oder nicht, somit ist das Problem vollständig behandelt.
Exceptions sind soweit ich weiß sehr langsam. Deswegen gilt es sie bei performanceorientierten Programmen zu vermeiden.
C++ ist aus meiner Sicht nicht dafür gemacht, Businessanwendungen zu bauen und dem Programmierer viel Ärger zu ersparen. Dafür sind andere Sprachen wesentlich besser geeignet (C#, Java, usw...) Wenn man C++ programmiert muss man so in den einen oder anderen sauren Apfel beißen. Weiterhin finde ich C und (jedoch weniger) C++ gute Lehrsprachen, weil alle Möglichkeiten bieten und gefähliche Konstrukte nicht verbieten. Das schult, um auch in andere Sprachen die Sprachmittel besser zu verstehen (z.b. Delegaten in C#) und effektivere Programme zu schreiben.
Wenn man es elegant und Softwaretechnologisch schön haben will, muss man aus meiner Sicht in C++ viel arbeit investieren und eigtl sogar besser eine andere Sprache verwenden.

VG,

Karlito
28.05.2013 14:21 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
Airblader Airblader ist männlich
Doppel-As


Dabei seit: 03.03.2013
Beiträge: 138
Herkunft: München

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Also ich nehme jetzt mal folgenden Code heran und hoffe, dass er das tut, was du meintest:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
#include <iostream>
#include <stdlib.h> 

using namespace std;

int main() {
    char eingabe[10];
    cin >> eingabe;
    
    char * pEnd;
    int ergebnis = strtol(eingabe, &pEnd, 10);
    
    if (pEnd == eingabe) {
        cout << "Eingabe ist kein Integer" << endl;
    } else {
        cout << "Eingegebene Zahl: " << ergebnis << endl;
    }
}


Hier bekomme ich für den Input "3a" die Ausgabe "Eingegebene Zahl: 3". Und wenn mein Ziel ist, zu überprüfen, ob eine Eingabe eine gültige Zahl ist, dann habe ich dieses Ziel hiermit nicht erreicht und hätte genauso gut einen simplen Cast verwenden können (dürfte dann auch schneller sein).

Vielleicht meintest du es ja aber auch anders?

__________________
The best thing about a boolean is that even if you're wrong, you're only off by a bit.
28.05.2013 15:01 Airblader ist offline Beiträge von Airblader suchen Nehmen Sie Airblader in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hallo,
Du hattest geschrieben:

Zitat:
Original von Airblader
Völlig analog sind beide Methoden dennoch nicht, für den Input "3a" gibt meine Variante zum Beispiel '3' zurück, strtol hingegen 0L. Bei "a3" liefern zum Beispiel beide 0 zurück.


Deshalb bin ich nicht davon ausgegangen, dass dein Programm 3 ausgibt... So ist das Verhalten tatsächlich sehr unschön. Habe auch gerade noch nicht herausgefunden warum dieses Codebeispiel für die Eingabe "3 a" funktioniert...

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
#include <iostream>
#include <stdlib.h> 
#include <string.h> 

using namespace std;

int main() {
    char eingabe[10];
    cin >> eingabe;
    
    char * pEnd;
    int ergebnis = strtol(eingabe, &pEnd, 10);
    
    if (pEnd != eingabe + strlen(eingabe)) {
        cout << "Eingabe ist kein Integer" << endl;
    } else {
        cout << "Eingegebene Zahl: " << ergebnis << endl;
    }
}


Ich hätte nicht erwartet, dass die Prüfung klappt.

VG,

Karlito
28.05.2013 16:26 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
eulerscheZahl eulerscheZahl ist männlich
Foren Gott


Dabei seit: 04.01.2013
Beiträge: 2.859

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

auch möglich:
code:
1:
2:
3:
4:
	if(*pEnd)
        cout << "Eingabe ist kein Integer" << endl;
	else 
        cout << "Eingegebene Zahl: " << ergebnis << endl;


cin liest nur bis zum nächsten Trennzeichen (' '; '\n') ein, daher kappt "3 a"

__________________
Syntax Highlighting fürs Board (Link)
28.05.2013 16:43 eulerscheZahl ist offline Beiträge von eulerscheZahl suchen Nehmen Sie eulerscheZahl in Ihre Freundesliste auf
Airblader Airblader ist männlich
Doppel-As


Dabei seit: 03.03.2013
Beiträge: 138
Herkunft: München

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Bei "3 a" sehe ich es ein, aber bei "3a" nicht. Augenzwinkern Wenn er nur soviel liest ist das ja auch eine andere Sache. Aber wenn er "3a" komplett einliest und beim Konvertieren daraus "3" macht, dann finde ich das irgendwie unschön.

__________________
The best thing about a boolean is that even if you're wrong, you're only off by a bit.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Airblader: 28.05.2013 17:35.

28.05.2013 17:34 Airblader ist offline Beiträge von Airblader suchen Nehmen Sie Airblader in Ihre Freundesliste auf
Karlito Karlito ist männlich
Kaiser


Dabei seit: 11.04.2011
Beiträge: 1.461

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Naja, bleibt halt, dass man schaut, ob der String bis zuende gelesen wurde. Ich finde das keine so schlimme Sache.

VG,

Karlito
28.05.2013 18:52 Karlito ist offline E-Mail an Karlito senden Beiträge von Karlito suchen Nehmen Sie Karlito in Ihre Freundesliste auf
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
Informatiker Board » Themengebiete » Praktische Informatik » C++ Eingabe überprüfen