mikrocontroller.net

Forum: PC-Programmierung char vergleichen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Michael B (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
switch (choice) {
  case 'A':
  printf("good morning");
  break;

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

  default:
  printf("wrong choice");
}

von DPA (Gast)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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)


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

von Timmo H. (masterfx)


Bewertung
0 lesenswert
nicht 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
#include <stdio.h>
#include <conio.h>

int main()
{
    char c;
    while(1){
        printf("Choice: ");
        c = getch();

        switch(c){
        case 'a':
            printf("\nGood morning.\n");
            break;
        case 'b':
            printf("\nGood evening.\n");
            break;
        case 'c':
            printf("\nExit Program.\n");
            return 0;
            break;
        default:
            printf("\nInvalid Input: %c\n",c);
        }
    }
    return 0;
}

: Bearbeitet durch User
von DPA (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Ich danke euch herzlich für eure Unterstützung.

von zitter_ned_aso (Gast)


Bewertung
0 lesenswert
nicht 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.
char choice;
printf("enter your choice:\n");
//falsch
scanf("%d", &choice);
//richtig
scanf("%c", &choice);
printf("choice = %c\n", choice);

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

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Bei Binary Data soll man ja jedes Bitmuster von EOF unterscheiden.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht 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().

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.