Forum: PC-Programmierung char vergleichen


von Michael B (Gast)


Lesenswert?

Hallo Zusammen,
als Einsteiger in C habe ich folgende Frage:
Ich möchte einen Program schreiben :
* Displays a simple menu with 3 choices
a) Good morning.
b) Good evening.
c) Exit Program.

* Asks the user to enter the required choice a, b or c.
* When user press a, b or c (without pressing enter key), then the 
program will delete the whole menu, display the corresponding entry (ex. 
Good morning, if user entered a , or exit the program if pressed c), 
after displaying the option wait for user to press any key, close the 
program when any key is pressed.
* If wrong input is entered (Not a, b or c), program clears the screen 
then prints "Wrong choice!", then it closes.


Meine Denkweise wäre so:

#include <stdio.h>
#include<stdlib.h>

int main()
{
char choice1 = 'A';
char choice2 = 'B';
char choice3 = 'C';
char choice;

printf("Enter your choice: ");
scanf("%d", &choice);
fflush(stdin);

if (choice =='A')
{
printf("Good Morning");
}

usw...

was mache ich hier falsch??

Vielen Dank für eure Hilfe

von Kristallkugel (Gast)


Lesenswert?

switch (choice) {
  case 'A':
  printf("good morning");
  break;

  case 'B':
  printf("good evening");
  break;

  default:
  printf("wrong choice");
}

von DPA (Gast)


Lesenswert?

1) a != A
2) %d -> Nummer, aber weder a noch A sind Nummern. Char ist %c: 
http://www.cplusplus.com/reference/cstdio/scanf/

von A. S. (Gast)


Lesenswert?

Michael B schrieb:
> without pressing enter key),

getchar statt scanf

Michael B schrieb:
> a) Good morning

Michael B schrieb:
> if (choice =='A')

Groß und klein

von DPA (Gast)


Lesenswert?

Und eventuell wäre getchar passender als scanf: 
http://www.cplusplus.com/reference/cstdio/getchar/

von Timmo H. (masterfx)


Lesenswert?

Michael B schrieb:
> scanf("%d", &choice);
Wartet auf Enter, soll aber ohne sein "(without pressing enter key)"
getch ist zwar nicht standardkonform, aber wäre eine Lösung
1
#include <stdio.h>
2
#include <conio.h>
3
4
int main()
5
{
6
    char c;
7
    while(1){
8
        printf("Choice: ");
9
        c = getch();
10
11
        switch(c){
12
        case 'a':
13
            printf("\nGood morning.\n");
14
            break;
15
        case 'b':
16
            printf("\nGood evening.\n");
17
            break;
18
        case 'c':
19
            printf("\nExit Program.\n");
20
            return 0;
21
            break;
22
        default:
23
            printf("\nInvalid Input: %c\n",c);
24
        }
25
    }
26
    return 0;
27
}

: Bearbeitet durch User
von DPA (Gast)


Lesenswert?

getchar hingegen ist standardkonform. Eventuell muss man dann aber das 
line buffering auf stdin ausschalten: 
http://www.cplusplus.com/reference/cstdio/setbuf/

Falls das aber irgend wann mal etwas ensthaftes werden soll, nimmt man 
am besten gleich ncurses.

von Dirk B. (dirkb2)


Lesenswert?

Michael B schrieb:
> char choice;
>
> scanf("%d", &choice);

Bei %d liest scanf eine Dezimalzahl (Ziffern) ein und speichert sie als 
int ab.

Ein int benötigt aber meist mehr Byte als ein char.
Da wird dann Speicher unzulässig überschrieben.

Der Compiler erkennt das mittlerweile und gibt dazu auch eine Warnung 
aus (wenn sie aktiviert sind)

Also Warnlevel hoch setzen (alle Warnungen aktivieren), die Warn7ngen 
beachten und deren Ursache beheben.

von Rolf M. (rmagnus)


Lesenswert?

DPA schrieb:
> getchar hingegen ist standardkonform. Eventuell muss man dann aber das
> line buffering auf stdin ausschalten:
> http://www.cplusplus.com/reference/cstdio/setbuf/

Wenn denn das Buffering nur innerhalb des Programms stattfindet und 
nicht schon im Terminal.

von Michael B (Gast)


Lesenswert?

Ich danke euch herzlich für eure Unterstützung.

von zitter_ned_aso (Gast)


Lesenswert?

Michael B schrieb:
> char choice;
>
> printf("Enter your choice: ");
> scanf("%d", &choice);



%d erwartet eine Zahl. Du gibst aber ein Zeichen (character) ein. Es 
wird nichts eingelesen und nichts überschrieben. Die Eingabe bleibt 
weiterhin im Buffer. Denn %d kann mit dieser Eingabe nichts anfangen.

Ruf danach noch mal scanf (diesmal aber richtig) auf und du wirst sehen, 
dass dein Zeichen eingelesen wird. Weil es im Buffer war.
1
char choice;
2
printf("enter your choice:\n");
3
//falsch
4
scanf("%d", &choice);
5
//richtig
6
scanf("%c", &choice);
7
printf("choice = %c\n", choice);

lieber getchar()/putchar() nehmen. Wobei diese Funktionen eine 
int-Variable erwarten ;-)

von Dirk B. (dirkb2)


Lesenswert?

zitter_ned_aso schrieb:
> lieber getchar()/putchar() nehmen. Wobei diese Funktionen eine
> int-Variable erwarten ;-)

Die geben ein int-Wert zurück. DerCompiler stutzt das dann - wenn nötig 
- bei der Zuweisung zurecht.
Das kann Probleme mit dem Vorzeichen geben, wenn man einen erweiterten 
Code benutzt (was bei Umlauten der Fall ist)


Beim scanf(" %c", &choice); sollte man vor dem %c ein Leerzeichen 
setzen.
Dies überliest mögliche Whitespace (z.B. die Entertaste einer vorherigen 
Eingabe)

Dies ist aber nur bei %c und %[ nötig, da alle anderen Formatspecifier 
dies automatisch tun.

von DPA (Gast)


Lesenswert?

Dirk B. schrieb:
> Die geben ein int-Wert zurück. DerCompiler stutzt das dann - wenn nötig
> - bei der Zuweisung zurecht.

Man sollte den Rückgabewert eventuell auf EOF prüfen, das wars dann aber 
auch schon.

> Das kann Probleme mit dem Vorzeichen geben, wenn man einen erweiterten
> Code benutzt (was bei Umlauten der Fall ist)

Blödsinn, das gibt immer nur ein byte oder EOF zurück. Bei 
Zeichencodierungen die mehr bytes brauchen muss man es halt entsprechend 
oft aufrufen. Oder anders gesagt, die kodierung ist dem ding egal.

von Rolf M. (rmagnus)


Lesenswert?

DPA schrieb:
>> Das kann Probleme mit dem Vorzeichen geben, wenn man einen erweiterten
>> Code benutzt (was bei Umlauten der Fall ist)
>
> Blödsinn,

Nein.

> das gibt immer nur ein byte oder EOF zurück. Bei Zeichencodierungen die
> mehr bytes brauchen muss man es halt entsprechend oft aufrufen. Oder
> anders gesagt, die kodierung ist dem ding egal.

Die Kodierung an sich schon, allerdings kann es, falls char 
vorzeichenbehaftet ist, bei negativen Werten (also in der Regel alles 
außerhalb des reinen ASCII-Wertebereichs) zu Problemen kommen. Dann 
liefert getchar in dem int nämlich die negativen Werte als positiv 
zurück. Das heißt, getchar erzeugt intern keinen char, sondern einen 
unsigned char und konvertiert den dann für die Rückgabe nach int. Und 
putchar erwartet es auch wieder in dieser Form. Wenn ich den Wert also 
zwischendurch nach char konvertiere, muss ich das berücksichtigen. Das 
gilt übrigens auch für printf mit %c.

Oder in Standard(C99)-Sprech:

"If the end-of-file indicator for the input stream pointed to by stream 
is not set and a next character is present, the fgetc function obtains 
that character as an unsigned char converted to an int and advances the
associated file position indicator for the stream (if defined)."

(getchar verweist auf getc und das wiederum auf fgetc)

Das ist eins von den Dingen, bei denen ich mich wirklich frage, was K&R 
damals geraucht haben, bevor sie das so entschieden haben.

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Bei Binary Data soll man ja jedes Bitmuster von EOF unterscheiden.

von Rolf M. (rmagnus)


Lesenswert?

Dirk B. schrieb:
> Bei Binary Data soll man ja jedes Bitmuster von EOF unterscheiden.

Das ist in der Praxis zwar üblicherweise gegeben, aber C lässt auch 
Implementationen zu, wo das nicht gilt. Deshalb gibt's die Funktion 
feof().

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.