Überprüfung ob Zahl oder Buchstabe

Gast #2507068
Lesenswert?

Hi,
habe folgendes Problem
1
unsigned short xpos;
2
unsigned short ypos;
3

4
do {
5
      cout << "Bitte geben Sie die x-Position des Feld-Elementes an: ";
6
      cin >> xpos;
7
      cin.ignore();
8
      cout << "Bitte geben Sie die y-Position des Feld-Elementes an: ";
9
      cin >> ypos;
10
      cin.ignore();
11

12
     if ((xpos < 1) || (xpos > 10) || (ypos < 1) || (ypos > 10) )
13
  cout << "Falsche Werte! Bitte zwischen 1 und 10" << endl;
14
  } while ((xpos < 1) || (xpos > 10) || (ypos < 1) || (ypos > 10));


Wie kann ich zusätzlich abfragen, ob xpos und ypos tatsächlich Zahlen 
zwischen 1 und 10 sind und nicht Buchstaben?
#2507089
Lesenswert?

> Wie kann ich zusätzlich abfragen, ob xpos und ypos tatsächlich
> Zahlen zwischen 1 und 10 sind und nicht Buchstaben?

Im Gegensatz zu meinen Vorrednern beantworte ich diese Frage in diesem 
Zusammenhang
1
  unsigned short xpos;
2
  ...
3
      cin >> xpos;

mit: gar nicht.
Du hast keine Chance das was du vorhast, so zu realisieren.

cin >> xpos;
ERWARTET, dass sich dein Benutzer an die Spielregeln hält und eine 
korrekte Zahlen-Eingabe abliefert. Du kannst hinten nach lediglich noch 
feststellen ob sich diese Zahl in dem von dir festgelegten Bereich 
befindet, so wie du das gemacht hast.

Wenn du das ändern willst, dann gibt es nur eine Möglichkeit:
Du musst deinen Benutzer erst mal seine Eingabe in einen String machen 
lassen, denn dort darf er alles eingeben.
Dann überprüft dein Programm, ob die Eingabe (=der String) den 
Erfordernissen genügt (sprich: ob in deinem Fall tatsächlich nur Zeichen 
im  für Digits erlaubten Bereich eingegeben wurden; da kommt dann 
isdigit ins Spiel) und erst dann kann dein Programm gefahrlos den String 
in die entsprechende Zahl umwandeln lassen. Aber solange du den kurzen, 
einfachen Weg mittels
cin >> xpos;
gehen willst, musst du darauf vertrauen, dass dein Benutzer nach den 
Regeln spielt.
Gast #2507128
Lesenswert?

Folgender Ansatz erkennt zwar, ob eine Zahl eingegeben wurde oder nicht.
Aber die while-Schleife rattert nach dem ersten Durchlauf durch (Eingabe 
xpos=4; ypos=z)
1
unsigned short xpos;
2
unsigned short ypos;  
3

4
do {
5
  cout << "Bitte geben Sie die x-Position des Feld-Elementes an: ";
6
  cin >> xpos;
7
  cin.ignore();
8

9
  if (((unsigned char) xpos) - '0' < 10)
10
       cout << "Du hast eine Zahl eingegeben\n";
11
  cout << "Bitte geben Sie die y-Position des Feld-Elementes an: ";
12

13
  cin >> ypos;
14
  cin.ignore();
15

16
  if (((unsigned char) ypos) - '0' < 10)
17
      cout << "Du hast eine Zahl eingegeben\n";
18

19
  
20
} while ((xpos < 1) || (xpos > 10) || (ypos < 1) || (ypos > 10) || (((unsigned char) ypos) - '0' > 10) || (((unsigned char) xpos) - '0' > 10) );
#2507138
Lesenswert?

Julio schrieb:
> Folgender Ansatz erkennt zwar, ob eine Zahl eingegeben wurde oder nicht.
> Aber die while-Schleife rattert nach dem ersten Durchlauf durch (Eingabe
> xpos=4; ypos=z)

siehe mein Beitrag weiter oben.

Wenn du den Weg gehen willst, dann ist getline und std::string in 
Kombination mit isdigit(), stringstream und dem >> Operator dein Freund.
#2507242
Lesenswert?

Rolf Magnus schrieb:
> Julio schrieb:
>> Folgender Ansatz erkennt zwar, ob eine Zahl eingegeben wurde oder nicht.
>> Aber die while-Schleife rattert nach dem ersten Durchlauf durch (Eingabe
>> xpos=4; ypos=z)
>
> Weil du den Fehlerzustand des Streams nicht zurücksetzt. So lange du das
> nicht tust, werden alle weiteren Leseoperationen nichts tun.

Es werden auch weitere Leseversuche sofort wieder abbrechen, solange er 
die ungültigen Zeichen aus dem Input nicht los wird.

Erfahrungsgemäss ist das alles aber mehr Aufwand als sich mittels 
getline einfach die Eingabe mal als String zu holen und dann 
auseinanderzunehmen.
Gast #2507253
Lesenswert?

Karl Heinz Buchegger schrieb:
> Rolf Magnus schrieb:
>> Julio schrieb:
>>> Folgender Ansatz erkennt zwar, ob eine Zahl eingegeben wurde oder nicht.
>>> Aber die while-Schleife rattert nach dem ersten Durchlauf durch (Eingabe
>>> xpos=4; ypos=z)
>>
>> Weil du den Fehlerzustand des Streams nicht zurücksetzt. So lange du das
>> nicht tust, werden alle weiteren Leseoperationen nichts tun.
>
> Es werden auch weitere Leseversuche sofort wieder abbrechen, solange er
> die ungültigen Zeichen aus dem Input nicht los wird.

Er hat ja ein cin.ignore() gemacht.

> Erfahrungsgemäss ist das alles aber mehr Aufwand als sich mittels
> getline einfach die Eingabe mal als String zu holen und dann
> auseinanderzunehmen.

Dann brauche ich aber doch einen stringstream, mit dem's dann auch 
wieder nicht anders ist. Die Variante mit dem getline und stringstream 
ist dann gut, wenn du die Eingaben immer zeilenweise verarbeiten willst 
bzw. ein anderes Trennzeichen hast, zwischen dem du noch was parsen 
willst (getline kann auch andere Zeichen statt Newline als Trenner 
nutzen).
#2507285
Lesenswert?

Rolf Magnus schrieb:

>>> nicht tust, werden alle weiteren Leseoperationen nichts tun.
>>
>> Es werden auch weitere Leseversuche sofort wieder abbrechen, solange er
>> die ungültigen Zeichen aus dem Input nicht los wird.
>
> Er hat ja ein cin.ignore() gemacht.

Hast recht. Hab ich überlesen

>> Erfahrungsgemäss ist das alles aber mehr Aufwand als sich mittels
>> getline einfach die Eingabe mal als String zu holen und dann
>> auseinanderzunehmen.
>
> Dann brauche ich aber doch einen stringstream, mit dem's dann auch
> wieder nicht anders ist. Die Variante mit dem getline und stringstream
> ist dann gut, wenn du die Eingaben immer zeilenweise verarbeiten willst
> bzw. ein anderes Trennzeichen hast, zwischen dem du noch was parsen
> willst (getline kann auch andere Zeichen statt Newline als Trenner
> nutzen).

Ist dann allerdings auch immer eine Frage, ob eine Eingabe von

  34a3

als fehlerhaft gewertet werden soll oder nicht.

  cin >> xpos;

würde sich die 34 rauspicken und den Stream nicht in einen Fehlerzustand 
versetzen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren