C: Mehrere Scanfs, wenn ich einen Wert für einen Scanf eingebe, wird der zweite Scanf übersprungen [duplicate]
Lesezeit: 4 Minuten
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?
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.
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.
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().
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!
Byeonggon Lee
You can also use scanf("%c%*c", &c);
to read two characters and ignore the last one (in this case ‘\n’)
13447800cookie-checkC: Mehrere Scanfs, wenn ich einen Wert für einen Scanf eingebe, wird der zweite Scanf übersprungen [duplicate]yes