Wie scanf ich für einzelne Zeichen in C [duplicate]

Lesezeit: 5 Minuten

Benutzeravatar von Yuval
Yuval

In C: versuche ich, char vom Benutzer mit zu bekommen scanf 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 nicht?

  • Nur um hier zu verdeutlichen, ob das C-Programm enthalten ist nur den Code oben, es wird wie erwartet funktionieren. Mögliche Probleme wie das von OP erwähnte treten nur auf, wenn es zusammen mit anderem E/A-Code verwendet wird, aus Gründen, die in der Antwort von PP erwähnt werden.

    – Forumgeber

    4. Januar 2018 um 11:00 Uhr


Das %c Der Konvertierungsspezifizierer überspringt nicht automatisch führende Leerzeichen, wenn es also einen verirrten Zeilenumbruch im Eingabestrom gibt (z. B. von einem vorherigen Eintrag), wird die scanf Anruf wird es sofort verbrauchen.

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

scanf(" %c", &c);

Das Leerzeichen in der Formatzeichenfolge sagt aus scanf um führende Leerzeichen zu überspringen, und das erste Nicht-Leerzeichen wird mit gelesen %c Konvertierungsbezeichner.

Vor allem vermeiden scanf(). Es ist den Schmerz nicht wert.

Sehen: Warum sagt jeder, dass man scanf nicht verwenden soll? Was sollte ich stattdessen verwenden?

Verwenden eines Leerzeichens in scanf() würde eine beliebige Anzahl von Leerzeichen im Eingabestrom ignorieren, was ist, wenn Sie mehr Eingaben lesen müssen? In Betracht ziehen:

#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() auf die gleiche Weise mit einem führenden Leerzeichen behoben werden kann, ist es nicht immer so einfach wie oben. Ein weiteres großes Problem ist, scanf() verwirft keine Eingabe im Eingabestream, wenn sie nicht dem Format entspricht. Zum Beispiel, wenn Sie eingeben abc für ein int wie zum Beispiel: scanf("%d", &int_var); dann abc müssen gelesen und verworfen werden. In Betracht ziehen:

#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 weiteres häufiges Problem ist das Mischen scanf() und fgets(). In Betracht ziehen:

#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 an fgets() wartet nicht auf die Eingabe, da der vom vorherigen Aufruf von scanf() hinterlassene Zeilenumbruch gelesen wird und fgets() das Lesen der Eingabe beendet, wenn es auf einen Zeilenumbruch trifft.

Es gibt viele andere ähnliche Probleme, die damit verbunden sind scanf(). Deshalb wird allgemein empfohlen, darauf zu verzichten.

Also, was ist die Alternative? Verwenden fgets() Funktion stattdessen wie folgt, 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, auf das Sie bei der Verwendung achten sollten fgets() liest das Newline-Zeichen ein, wenn genügend Platz im Eingabepuffer vorhanden ist. Wenn es nicht erwünscht 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 */

Das funktioniert bei mir probier es aus

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

  • Das ist jetzt wild! Würden Sie erklären, warum der Platz davor %c macht einen Unterschied?

    – Max Coplan

    10. September 2019 um 15:59 Uhr

  • Gelöst: überprüfen diese aus

    – Max Coplan

    10. September 2019 um 16:02 Uhr

  • Dies scheint nicht mehr Informationen hinzuzufügen als die akzeptierte Antwort von 2012.

    – Domson

    6. Januar 2020 um 18:05 Uhr

Benutzeravatar von Sanberk
Sanberk

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

Während Sie an Visual Studio arbeiten, erhalten Sie möglicherweise einen Fehler wie:

‘scanf’: Funktion oder Variable ist möglicherweise unsicher. Erwägen Sie die Verwendung scanf_s stattdessen. Um die Verwerfung zu deaktivieren, verwenden Sie _CRT_SECURE_NO_WARNINGS

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 nullterminierte Zeichenfolgen gelesen werden, werden Ganzzahlen als Breitenangabe und Puffergröße verwendet.

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

Weder fgets noch getchar funktionieren, um das Problem zu lösen. Die einzige Problemumgehung besteht darin, ein Leerzeichen vor %c zu lassen, während scanf verwendet wird scanf(” %c”,ch); // wird nur funktionieren

Im Folgenden funktionieren fgets 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);

versuchen Sie es mit getchar (); stattdessen

Syntax:

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

Benutzeravatar von mpromonet
mpromonet

Vor dem scanf setzen fflush(stdin); Puffer zu löschen.

  • fflush(stdin); ist undefiniertes Verhalten nach C-Norm.

    – PP

    2. Dezember 2016 um 19:05 Uhr


  • Das ist nicht richtig, fflush(stdin) ist UB, erwähnt in vielen Fragen bei SO.

    – baumelnder Zeiger

    19. Januar 2018 um 9:17 Uhr

  • Es funktioniert mit dem Microsoft-Compiler, aber das war es auch schon

    – WENDYN

    21. Juni 2020 um 16:34 Uhr

1423400cookie-checkWie scanf ich für einzelne Zeichen in C [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy