ASCII Wert einer char Variable in eine int Variable konvertieren
-
Moin!
Ich möchte für mein Programm eine Tastatureingabe in ein char Array speichern. Dieses überprüfe ich dann einzeln auf ungültige Eingaben.
Dafür brauche ich jedoch den ASCII Code jedes einzelnen Zeichens.
Per Googel finde ich lediglich, wie man sich den ASCII Wert anzeigen lassen kann. Ich benötige ihn jedoch zum vergleichen in einer If-Anweisung.
Für ein besseres Verständnis meines Problems, habe ich unten meinen gesamten Programmcode beigefügt. Die zu verbessernde Stelle ist markiert.
Ich danke im vroaus für jede Hilfe!
Kritik über meinen Programmirstil darf gerne geäußert werden, aber dann auch bitte mein Problem lösen.
/* Es soll eine Zufallszahl zwischen 1 und 100 generiert werden. Dann hat der Nutzer 6 Versuche diese zu erraten. Es soll angezeigt werden, ob die Zahl höher oder niedriger als die eingegebene Zahl ist. */ #include <iostream> #include <iomanip> #include <time.h> using namespace std; int ZufallszahlGenerator(); bool EingabeCheck(char); int ZahlVergleich(int, int); void Ausgabe(int, int, int); int main() { bool schleife = true; int zZahl; srand((unsigned)time(NULL)); //Dadurch wird der Zufallsgenerator initialisiert! srand ist eine Standardfunktion! while (schleife == true) { zZahl = ZufallszahlGenerator(); cout << "Willkommen!\nSie haben sechs Versuche um die Zahl zu erraten.\nViel Glueck!\n\n"; for (int i = 1; i <= 6; i++) { char eingabe[2]; bool eingabeok; cout << i << ". Versuch: "; cin >> eingabe; //überprüfen, ob Buchstaben oder Sonderzeichen vorhanden sind for (int e = 0; e <= 2; e++) { eingabeok = EingabeCheck(eingabe[e]); //Wenn Zeichen ok, true zurück. Sonst false. } //Wenn kein Sonderzeichen vorhanden, fahre im Programm fort if (eingabeok == true) { int eingabee = (int)eingabe; int ergebnis = ZahlVergleich(zZahl, eingabee); Ausgabe(ergebnis, zZahl, i); if (ergebnis == 1) i = 7; } else { cout << "Ihre Eingabe ist leider ungueltig!\nIhr missglueckter Versuch wird Ihnen gut geschrieben.\n"; --i; } } } } int ZufallszahlGenerator() { int zZahl = rand() % 100 + 1; return zZahl; } //HIER IST DAS PROBLEM - ANFANG bool EingabeCheck(char zeichen) { bool rueckgabe; if (zeichen > 47 && zeichen < 58) { rueckgabe = true; } else { rueckgabe = false; } return rueckgabe; } //HIER IST DAS PROBLEM - ENDE int ZahlVergleich(int zZahl, int eingabe) { int rueckgabewert; if (eingabe == zZahl) { rueckgabewert = 1; } else if (eingabe < zZahl) { rueckgabewert = 2; } else if (eingabe > zZahl) { rueckgabewert = 3; } return rueckgabewert; } void Ausgabe(int ergebnis, int zZahl, int versuchsanzahl) { if (ergebnis == 1) { cout << "\nGratulation!!!\nSie haben beim " << versuchsanzahl << ". Versuch die Zahl " << zZahl << "erraten.\n\n\n"; } else if (ergebnis == 2) { cout << "Ihre eingegebene Zahl ist kleiner als die zufaellig generierte Zahl.\n"; } else if (ergebnis == 3) { cout << "Ihre eingegebene Zahl ist groesser als die zufaellig generierte Zahl.\n"; } }
-
Was ist das Problem? Die Funktion scheint erst mal korrekt zu sein, der Aufruf eher nicht.
-
Die ASCII-Werte sollte man bei Chars aber eher nicht verwenden:
if (zeichen >= '0' && zeichen <= '9')
(auch wenn es bei EBCDIC i.A. nicht laufen wird, aber es geht hier um die Lesbarkeit)
-
Th69 schrieb:
if (zeichen >= '0' && zeichen <= '9')
(auch wenn es bei EBCDIC nicht laufen wird, aber es geht hier um die Lesbarkeit)
Doch! '0' bis '9' sind vom Sprachstandard garantiert, 'a' bis 'z' nicht (und das ist auch, was bei EBCDIC nicht funktioniert).
-
Recht hat der Sepp:
[lex.charset]/3 schrieb:
In both the source and execution basic character sets, the value of each character after
0
in the above list of decimal digits shall be one greater than the value of the previous.
-
Bei einem Vergleich auf >, ==, < wird i.A +1, 0 ,-1 zurück gegeben. (Oder auch >0, 0, <0 )
-
DirkB schrieb:
Bei einem Vergleich auf >, ==, < wird i.A +1, 0 ,-1 zurück gegeben. (Oder auch >0, 0, <0 )
Ich verstehe gerade nicht genau was du meinst.
Könntest du das vielleicht nochmal erklären? Danke!Das ich bei einem char direkt mit den Zeichen vergleichen kann (wenn es Nummern sind) wusste ich noch nicht. Danke für den Tipp!
Ja, mein Aufruf ist fehlerhaft. Das habe ich inzwischen durch weitere Tests herausgefunden.
Ich rätsel aber noch, wie ich ihn besser hinbekomme.Vielleicht, wenn ich jedes Feld im eingabe Array einzeln und direkt überprüfe und dann, wenn es eine Zahl ist, diese Zahl dann mit 1 / 10 / 100 multipliziere und in eine neue int Variable speichere? (Die Werte werden dann addiert)
Oder denke ich da jetzt zu kompliziert?
-
Nowaepon schrieb:
DirkB schrieb:
Bei einem Vergleich auf >, ==, < wird i.A +1, 0 ,-1 zurück gegeben. (Oder auch >0, 0, <0 )
Ich verstehe gerade nicht genau was du meinst.
Könntest du das vielleicht nochmal erklären? Danke!Das soll heißen, dass der Rückgabewert deiner Funktion (und damit die Benutzung der Funktion an sich) äußerst unintuitiv ist.
-
Ah!
Danke sehr!
Da hat er natürlich recht.Ein Freund hat mir jetzt ein bisschen unter die Arme gegriffen.
Jetzt läufts.Hier mal der neue Code für euch:
#include <iostream> #include <iomanip> #include <time.h> using namespace std; int ZufallszahlGenerator(); int ZahlVergleich(int, int); void Ausgabe(int, int, int); int EingabeMitPruefung(int, int, int); int main() { bool schleife = true; int zZahl; srand((unsigned)time(NULL)); //Dadurch wird der Zufallsgenerator initialisiert! srand ist eine Standardfunktion! while (schleife == true) { zZahl = ZufallszahlGenerator(); cout << "Willkommen!\nSie haben sechs Versuche um die Zahl zu erraten.\nViel Glueck!\n\n"; for (int i = 1; i <= 6; i++) { int eingabe, eingabeok; eingabe = EingabeMitPruefung(1, 100, i); //Rückgabewert ist die auf Sonderzeichen und Buchstaben geprüfte Eingabe //Wenn kein Sonderzeichen vorhanden, fahre im Programm fort int ergebnis = ZahlVergleich(zZahl, eingabe); Ausgabe(ergebnis, zZahl, i); if (ergebnis == 1) { i = 7; } else if (i == 6) { ergebnis = 0; Ausgabe(ergebnis, zZahl, i); } } } } int ZufallszahlGenerator() { int zZahl = rand() % 100 + 1; return zZahl; } int ZahlVergleich(int zZahl, int eingabe) { int rueckgabewert; if (eingabe == zZahl) { rueckgabewert = 1; } else if (eingabe < zZahl) { rueckgabewert = 2; } else if (eingabe > zZahl) { rueckgabewert = 3; } return rueckgabewert; } void Ausgabe(int ergebnis, int zZahl, int versuchsanzahl) { if (ergebnis == 0) { cout << "\nSchade!!!\nSie haben die Zufallszahl " << zZahl << " auch nach dem " << versuchsanzahl << ". Versuch nicht erraten.\n\n\n\n"; } else if (ergebnis == 1) { cout << "\nGratulation!!!\nSie haben beim " << versuchsanzahl << ". Versuch die Zahl " << zZahl << " erraten.\n\n\n\n"; } else if (ergebnis == 2) { cout << "\tIhre eingegebene Zahl ist kleiner als die zufaellig generierte Zahl.\n"; } else if (ergebnis == 3) { cout << "\tIhre eingegebene Zahl ist groesser als die zufaellig generierte Zahl.\n"; } } int EingabeMitPruefung(int min, int max, int versuchnummer) { while (true) //Wiederhohle für immer, Schleife wird über return verlassen { int eingabe; cout << versuchnummer << ". Versuch: "; cin >> eingabe; if (cin.fail()) { //Fehlerhafte Eingabe cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "\tBuchstaben und Sonderzeichen werden nicht unterstützt!\n"; } else { if (eingabe >= min && eingabe <= max) { //korrekte Eingabe return eingabe; //Wert zurück geben } else { //außerhalb des erwarteten Bereichs cout << "\tEs sind nur Zahlen zwischen " << min << " und " << max << " zulaessig.\n"; } } } }
Vielen Dank für eure Hilfe!
-
Sorry für das Mißverständnis bzgl. EPCDIC - ich meinte, daß es generell bei solchen Vergleichen von Zeichen im Allgemeinen keine einheitliche Lösung für ASCII und EPSDIC geben kann (dann sollte man natürlich auf die Funktionen isupper, islower, isdigit etc zurückgreifen). Daß das gezeigte Beispiel mit den Zahlen gerade für beide funktioniert, ist natürlich ein fail meinserseits
Mir ging es nur darum, daß der TE lernt, daß man direkt im Code die Zeichen benutzen kann. Aber daß er nicht davon ausgehen kann, daß es nur ASCII gibt, sondern evtl. auch andere Codierungen (auch wenn diese auf den heutigen Systemen eher selten sind).
Bei Umlauten jedoch beispielsweise gibt es dann aber wieder ähnliche Probleme (Encoding, Codepages etc.)...
-
Ok, wenn´s jetzt läuft darf man vermutlich auch Kritik an deinem Programmierstil äußern, ohne auf die Ausgangsfrage einzugehen:
- benutze aussagekräftige Variablennamen.
schleife
deutet zwar an, dass sie für Schleifendurchläufe benutzt wird, aber nicht, welchen Zweck sie erfüllt.ZahlGeraten
wäre da ein besserer Name.- der Trick mit der 7, um die for-Schleife abzubrechen, ist nicht schön. Das kann man besser mit in die while Schleife nehmen, zusammen mit dem Variablennamen könnte das so aussehen:
int main() { bool ZahlGeraten = false; unsigned int Versuche = 0; while( !ZahlGeraten && Versuche < 7 ) { ... ++Versuche; } if( ZahlGeraten ) { // Erfolg, in Versuche steht die Anzahl der Versuche, die der Benutzer gebraucht hat } else { // Zahl wurde nicht erraten } }
- vermeide temporäre Variablen, die nur zu Rückgabezwecken benutzt werden. Für den Compiler macht´s wahrscheinlich keinen Unterschied, aber jede überflüssige Codezeile ist eine zu viel.
int Zahlvergleich( int Zahl, int Eingabe ) { if( Zahl == Eingabe ) { return 1; } else if( Zahl < Eingabe ) { return 2; } else if( Zahl > Eingabe ) { return 3; } }
- benutze niemals C-Style casts wie in Zeile 15, sondern immer die entsprechenden C++ Pendants.
- 1,2 und 3 als Rückgabewerte sind unglücklich gewählt, aber das hat dir Dirk B. ja schon gesagt.
- Warum benutzt du Präfixe für
zZahl
, aber keine fürschleife
? Am besten lässt du alle weg und benutzt gar keine. Für Member kann man Ausnahmen machen, indem man ihnen z.B. einm
voranstellt oder ein_
anhängt.- Benutze Variablen so lokal wie möglich.
zZahl
wird erst in derwhile
Schleife gebraucht und braucht also erst dort definiert zu werden.Edit:
Bugfix