C: Mehrere Scanfs, wenn ich einen Wert für einen Scanf eingebe, wird der zweite Scanf übersprungen [duplicate]

Lesezeit: 4 Minuten

Benutzer-Avatar
Schnee_Mac

Ich habe diesen Codeblock (Funktionen weggelassen, da die Logik Teil einer Hausaufgabe ist):

#include <stdio.h>

int main()
{
    char c="q";
    int size; 

    printf("\nShape (l/s/t):");
    scanf("%c",&c);

    printf("Length:"); 
    scanf("%d",&size);

    while(c!='q')
    {
        switch(c)
        {
            case 'l': line(size); break; 
            case 's': square(size); break;
            case 't': triangle(size); break; 
        }


        printf("\nShape (l/s/t):");
        scanf("%c",&c);

        printf("\nLength:"); 
        scanf("%d",&size);
    }

    return 0; 
}

Die ersten beiden Scanfs funktionieren großartig, kein Problem, sobald wir in die While-Schleife kommen. Ich habe ein Problem, bei dem, wenn Sie aufgefordert werden sollen, ein neues Shape-Zeichen einzugeben, es stattdessen nach unten springt printf von Length und wartet darauf, von dort eine Eingabe für ein Zeichen zu erhalten, später dann eine Dezimalzahl bei der nächsten Iteration der Schleife.

Preloop-Iteration:

Scanf: Form. Funktioniert super
Scanf: Länge. Kein Problem

Schleife 1.

Scanf: Form. Überspringt diese
Scanf: Länge. Problem, dieses Scanf wird dem Formzeichen zugeordnet.

Schleife 2
Scanf: Form. Überspringt diese
Scanf: Länge. Problem, dieses Scanf wird jetzt der Größe int zugeordnet.

Warum tut es das?

Benutzer-Avatar
Thomas Padron-McCarthy

scanf("%c") liest das Newline-Zeichen aus der EINTRETEN Schlüssel.

Sagen wir, wenn Sie tippen 15geben Sie a ein 1a 5 und drücken Sie dann die EINTRETEN Schlüssel. Es befinden sich also jetzt drei Zeichen im Eingabepuffer. scanf("%d") liest die 1 und die 5interpretiert sie als die Zahl 15, aber das Zeilenumbruchzeichen befindet sich noch im Eingabepuffer. Das scanf("%c") liest sofort dieses Newline-Zeichen und das Programm geht dann zum nächsten über scanf("%d")und warten Sie, bis Sie eine Zahl eingeben.

Der übliche Rat lautet, ganze Eingabezeilen mit zu lesen fgets, und interpretieren Sie den Inhalt jeder Zeile in einem separaten Schritt. Eine einfachere Lösung für Ihr unmittelbares Problem ist das Hinzufügen von a getchar() nach jedem scanf("%d").

  • Das scanf("%d"); getchar(); Die Kombination schlägt fehl, wenn der Benutzer versehentlich ein Leerzeichen (oder anderen Müll) nach der Zahl eingibt.

    – Ilkkachu

    11. Juni 2017 um 10:14 Uhr

Das Grundproblem ist das scanf() lässt den Zeilenumbruch hinter der Zahl im Puffer stehen und liest dann mit %c beim nächsten Pass. Eigentlich ist dies eine gute Demonstration dafür, warum ich es nicht benutze scanf(); Ich benutze einen Zeilenleser (fgets()zum Beispiel) und sscanf(). Es ist einfacher zu kontrollieren.

Sie können es wahrscheinlich retten, indem Sie verwenden " %c" Anstatt von "%c" für den Formatstring. Das Leerzeichen verursacht scanf() um Leerzeichen (einschließlich Zeilenumbrüche) zu überspringen, bevor das Zeichen gelesen wird.

Aber es wird auf lange Sicht einfacher sein, aufzugeben scanf() und fscanf() und verwenden fgets() oder gleichwertig plus sscanf(). Abgesehen von allem anderen ist das Melden von Fehlern viel einfacher, wenn Sie mit der gesamten Saite arbeiten können, nicht mit den Tröpfchen, die zurückgelassen werden scanf() nachdem es fehlschlägt.

Sie sollten auch immer prüfen, ob Sie einen umgerechneten Wert erhalten scanf(). Die Eingabe schlägt fehl – ​​routinemäßig und schrecklich. Lassen Sie Ihr Programm nicht ruinieren, weil Sie es nicht überprüft haben.

Benutzer-Avatar
Jon Z.

Versuchen Sie, in scanf ein Leerzeichen hinzuzufügen.

scanf(" %d", &var);
//     ^
//   there

Dies wird verursachen scanf() um alle Leerzeichen zu verwerfen, bevor eine Ganzzahl gefunden wird.

  • Entsprechend Abschnitt 7.21.6.2p8, scanf möchten normalerweise verwerfen Sie alle Leerzeichen, bevor Sie eine Ganzzahl finden, wodurch die Leerzeichen in dieser Formatzeichenfolge sinnlos werden: “Eingegebene Leerzeichen (wie von der isspace-Funktion angegeben) werden übersprungen, es sei denn, die Spezifikation enthält a [, c, or n specifier.”

    – autistic

    Feb 21, 2017 at 2:14

  • This won’t fix the issue. %d already skips leading whitespace characters.

    – Spikatrix

    Feb 21, 2017 at 2:43

user avatar
noMAD

Use the function

void seek_to_next_line( void )
{
    int c;
    while( (c = fgetc( stdin )) != EOF && c != '\n' );
}

to clear out your input buffer.

user avatar
Gargi Srinivas

The '\n' character is still left on the input stream after the first call to scanf is completed, so the second call to scanf() reads it in. Use getchar().

user avatar
guga

When you type the shape and ENTER, the shape is consumed by the first scanf, but the ENTER is not! The second scanf expects a number so, the ENTER is skipped because is considered a white space, and the scanf waits for a valid input ( a number) that, again, is terminated by the ENTER. Well, the number is consumed, but the ENTER is not, so the first scanf inside the while uses it and your shape prompt is skipped… this process repeats. You have to add another %c in the scanfs to deal with the ENTER key. I hope this helps!

user avatar
Byeonggon Lee

You can also use
scanf("%c%*c", &c);
to read two characters and ignore the last one (in this case ‘\n’)

1344780cookie-checkC: Mehrere Scanfs, wenn ich einen Wert für einen Scanf eingebe, wird der zweite Scanf übersprungen [duplicate]

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

Privacy policy