Forum: PC-Programmierung Überprüfung ob Zahl oder Buchstabe


von Julio (Gast)


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?

von Helmut L. (helmi1)


Lesenswert?

isdigit(x)

in ctype.h

von Infinity (Gast)


Lesenswert?

Indem du dir mal die ASCII-Tabelle anschaust und feststellst, dass 
Buchstaben und Zahlen in einem bestimmten Bereich der ASCII-Tabelle 
liegen.

So ermittelst du einfach den ASCII-Wert des eingegebenen Zeichens und 
schaust dann, ob dieser in einem bestimmten Bereich liegt.


Gruß

von Karl H. (kbuchegg)


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.

von Stefan (Gast)


Lesenswert?

if (((unsigned char) x) - '0' < 9)
Stefan

von Stefan (Gast)


Lesenswert?

sorry falsch < 10
Stefan

von Julio (Gast)


Lesenswert?

>isdigit(x)
>in ctype.h


isdigit funktioniert aber nur mit 'char' und nicht mit 'unsigned short' 
oder?

von Julio (Gast)


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) );

von Karl H. (kbuchegg)


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.

von Stefan (Gast)


Lesenswert?

>> Folgender Ansatz erkennt zwar, ob eine Zahl eingegeben wurde oder nicht.
Und ich dachte das war die Frage.
Stefan

von Rolf Magnus (Gast)


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)

Weil du den Fehlerzustand des Streams nicht zurücksetzt. So lange du das 
nicht tust, werden alle weiteren Leseoperationen nichts tun.

von Karl H. (kbuchegg)


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.

von Rolf Magnus (Gast)


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).

von Karl H. (kbuchegg)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.