web-dev-qa-db-de.com

Wie scanne ich ein einzelnes Zeichen in C ein?

In C: Ich versuche, mit scanf vom Benutzer Zeichen zu bekommen, und wenn ich es ausführe, wartet das Programm nicht darauf, dass der Benutzer etwas eingibt ...

Dies ist der Code:

char ch;
printf("Enter one char");
scanf("%c", &ch);
printf("%c\n",ch);

Warum funktioniert das nicht?

71
Yuval

Der %c-Konvertierungsspezifizierer überspringt nicht automatisch führende Leerzeichen. Wenn sich also im Eingabestrom (von einem vorherigen Eintrag) eine verirrte Zeilenumbrüche befinden, wird der Aufruf scanf ihn sofort verbrauchen.

Eine Möglichkeit, das Problem zu umgehen, besteht darin, ein Leerzeichen vor dem Konvertierungsbezeichner in der Formatzeichenfolge einzufügen:

scanf(" %c", &c);

Das Leerzeichen in der Formatzeichenfolge weist scanf an, führende Whitespaces zu überspringen, und das erste Nicht-Whitespace-Zeichen wird mit dem %c-Konvertierungsspezifizierer gelesen. 

190
John Bode

Vermeiden Sie zunächst scanf(). Die Verwendung lohnt sich nicht.

Siehe: Warum sagt jeder, dass scanf nicht verwendet wird? Was soll ich stattdessen verwenden?

Die Verwendung eines Whitespace-Zeichens in scanf() würde eine beliebige Anzahl von Whitespace-Zeichen im Eingabestrom ignorieren. Was ist, wenn Sie mehr Eingaben lesen müssen? Erwägen:

#include <stdio.h>

int main(void)
{
   char ch1, ch2;

   scanf("%c", &ch1);  /* Leaves the newline in the input */
   scanf(" %c", &ch2); /* The leading whitespace ensures it's the
                          previous newline is ignored */
   printf("ch1: %c, ch2: %c\n", ch1, ch2);

   /* All good so far */

   char ch3;
   scanf("%c", &ch3); /* Doesn't read input due to the same problem */
   printf("ch3: %c\n", ch3);

   return 0;
}

Während das 3. scanf () mit einem führenden Whitespace auf dieselbe Weise behoben werden kann, ist es nicht immer so einfach wie oben beschrieben .. Ein weiteres Problem ist, dass scanf() keine Eingabe im Eingabestrom verwirft, wenn dies nicht der Fall ist. t stimmt mit dem Format überein. Wenn Sie beispielsweise abc für eine int eingeben, wie: scanf("%d", &int_var);, muss abc lesen und verwerfen. Erwägen:

#include <stdio.h>

int main(void)
{
    int i;

    while(1) {
        if (scanf("%d", &i) != 1) { /* Input "abc" */
            printf("Invalid input. Try again\n");
        } else {
            break;
        }
    }

    printf("Int read: %d\n", i);
    return 0;
}

Ein anderes häufiges Problem ist das Mischen von scanf() und fgets(). Erwägen:

#include <stdio.h>

int main(void)
{
    int age;
    char name[256];
    printf("Input your age:");
    scanf("%d", &age); /* Input 10 */
    printf("Input your full name [firstname lastname]");
    fgets(name, sizeof name, stdin); /* Doesn't read! */
    return 0;
}

Der Aufruf von fgets() wartet nicht auf eine Eingabe, da die durch den vorherigen Aufruf von scanf () hinterlassene neue Zeile gelesen wird und fgets () das Lesen der Eingabe beendet, wenn er auf eine neue Zeile trifft.

Es gibt viele andere ähnliche Probleme im Zusammenhang mit scanf(). Deshalb wird es generell empfohlen, dies zu vermeiden.

Also, was ist die Alternative? Verwenden Sie stattdessen die Funktion fgets() , um ein einzelnes Zeichen zu lesen:

#include <stdio.h>

int main(void)
{
    char line[256];
    char ch;

    if (fgets(line, sizeof line, stdin) == NULL) {
        printf("Input error.\n");
        exit(1);
    }

    ch = line[0];
    printf("Character read: %c\n", ch);
    return 0;
}

Ein Detail, das Sie bei der Verwendung von fgets() beachten sollten, liest das Zeilenumbruchzeichen ein, wenn im Inut-Puffer genügend Platz vorhanden ist. Wenn es nicht wünschenswert ist, können Sie es entfernen:

char line[256];

if (fgets(line, sizeof line, stdin) == NULL) {
    printf("Input error.\n");
    exit(1);
}

line[strcpsn(line, "\n")] = 0; /* removes the trailing newline, if present */
12
P.P.

Hier ist eine ähnliche Sache, die ich gerne teilen möchte,

während Sie an Visual Studio arbeiten, erhalten Sie möglicherweise eine Fehlermeldung wie 'scanf': Funktion oder Variable können unsicher sein. Verwenden Sie stattdessen scanf_s. Verwenden Sie _CRT_SECURE_NO_WARNINGS, um die Abschreibung zu deaktivieren

Um dies zu verhindern, sollten Sie es im folgenden Format schreiben

Ein einzelnes Zeichen kann wie folgt gelesen werden:

char c;
scanf_s("%c", &c, 1);

Wenn mehrere Zeichen für nicht mit Null abgeschlossene Zeichenfolgen gelesen werden, werden Ganzzahlen als Breitenangabe und Puffergröße verwendet.

char c[4];
scanf_s("%4c", &c, _countof(c));

Grüße,

1
Sanberk

weder fgets noch getchar können das Problem lösen. Die einzige Problemumgehung besteht darin, ein Leerzeichen vor% c einzuhalten, während scanf verwendet wird. // funktioniert nur

In den folgenden fgets funktioniert auch nicht ..

char line[256];
char ch;
int i;

printf("Enter a num : ");
scanf("%d",&i);
printf("Enter a char : ");

if (fgets(line, sizeof line, stdin) == NULL) {
    printf("Input error.\n");
    exit(1);
}

ch = line[0];
printf("Character read: %c\n", ch);
0
CoderTag

Das funktioniert für mich, probiere es aus

int main(){
char c;
scanf(" %c",&c);
printf("%c",c);
return 0;
}
0
Praveen samuel

Vor dem Scanf fflush(stdin); zum Löschen des Puffers. 

0

versuchen Sie es mit getchar (); stattdessen

syntax:

void main() {
    char ch;
    ch = getchar();
}
0
kesarling

Sie müssen eine gültige Variable verwenden. ch ist keine gültige Variable für dieses Programm. Verwenden Sie char Aaa

char aaa;
scanf("%c",&Aaa);

Getestet und es funktioniert.

0
AL Maruf

Stellt ein Leerzeichen vor dem% c-Konvertierungsspezifizierer bereit, sodass der Compiler Leerzeichen ignoriert. Das Programm kann wie folgt geschrieben werden:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char ch;
    printf("Enter one char");
    scanf(" %c", &ch); /*Space is given before %c*/
    printf("%c\n",ch);
return 0;
}
0
Shahid Nawaz