Ich habe folgendes Programm:
int main(int argc, char *argv[])
{
int a, b;
char c1, c2;
printf("Enter something: ");
scanf("%d",&a); // line 1
printf("Enter other something: ");
scanf("%d", &b); // line 2
printf("Enter a char: ");
scanf("%c",&c1); // line 3
printf("Enter another char: ");
scanf("%c", &c2); // line 4
printf("Done"); // line 5
system("PAUSE");
return 0;
}
Wie ich im C-Buch gelesen habe, sagt der Autor das scanf()
ein neues Zeilenzeichen im Puffer belassen wurde. Daher stoppt das Programm nicht in Zeile 4, damit der Benutzer die Daten eingeben kann, sondern speichert das neue Zeilenzeichen in c2 und wechselt zu Zeile 5.
Ist das richtig?
Kommt dies jedoch nur bei char
Datentypen vor? Weil ich dieses Problem bei int
Datentypen wie in Zeile 1, 2, 3 nicht gesehen habe. Ist es richtig?
fflush(stdin)
vor dem Aufrufscanf()
für ein einzelnes Zeichen verwendet werden kann. Bitte lesen Sie Verwendenfflush(stdin)
für eine Diskussion der Vor- und Nachteile und Alternativen zu dieser Methode (die mehr oder weniger unter Windows funktioniert und an den meisten anderen Orten nicht funktioniert).Antworten:
Die
scanf()
Funktion überspringt führende Leerzeichen automatisch, bevor versucht wird, andere Konvertierungen als Zeichen zu analysieren. Die Zeichenformate (hauptsächlich%c
; auch Scan-Sets%[…]
- und%n
) sind die Ausnahme; Sie überspringen keine Leerzeichen.Mit
" %c"
einem führenden Leerzeichen verwenden, um optionale Leerzeichen zu überspringen. Verwenden Sie kein abschließendes Leerzeichen in einerscanf()
Formatzeichenfolge.Beachten Sie, dass dies immer noch kein nachfolgendes Leerzeichen im Eingabestream verbraucht, auch nicht bis zum Ende einer Zeile. Achten Sie also darauf, wenn Sie auch denselben Eingabestream verwenden
getchar()
oder verwendenfgets()
. Wir veranlassen scanf nur, vor der Konvertierung Leerzeichen zu überspringen , wie dies bei%d
und anderen Konvertierungen ohne Zeichen der Fall ist .Beachten Sie, dass andere "Nicht-Leerzeichen" -Direktiven (um die POSIX-Scanf-Terminologie zu verwenden ) als Konvertierungen, wie der Literaltext in,
scanf("order = %d", &order);
auch keine Leerzeichen überspringen. Das Literalorder
muss mit dem nächsten zu lesenden Zeichen übereinstimmen.Also willst du wahrscheinlich
" order = %d"
dort sein, wenn Sie eine neue Zeile aus der vorherigen Zeile überspringen möchten, aber dennoch eine wörtliche Übereinstimmung für eine feste Zeichenfolge wie diese Frage benötigen .quelle
%c
,%n
,%[]
Sind die 3 angegebenen Erwartungen , die führenden Leerzeichen nicht verbrauchen.scanf()
Format - String undscanf()
fragt zweimal für die Eingabe , während ich es erwarte , nur einmal zu fragen , für eine Diskussion über folgende Leerzeichen in Formatstrings. Sie sind eine schlechte Idee - erstaunlich schlecht, wenn Sie menschliche Interaktion erwarten und schlecht für die Programminteraktion.Verwenden Sie
scanf(" %c", &c2);
. Dies wird Ihr Problem lösen.quelle
Eine andere Option (die ich von hier bekommen habe ) ist das Lesen und Verwerfen der Zeilenumbruch mithilfe der Option zur Unterdrückung der Zuweisung . Dazu setzen wir einfach ein Format ein, um ein Zeichen mit einem Sternchen zwischen
%
und zu lesenc
:scanf
liest dann das nächste Zeichen (dh die neue Zeile), weist es jedoch keinem Zeiger zu.Am Ende würde ich jedoch die letzte Option der FAQ unterstützen :
quelle
a
Leerzeichen und dann Zeilenumbruch eingibt, die unterdrückte Zeichenkonvertierung den Leerzeichen liest und dennoch den Zeilenumbruch verlässt. Wenn der Benutzer wiesupercalifragilisticexpialidocious
erwartet tippta
, müssen Sie mit vielen zusätzlichen Zeichen umgehen. Sie können auch nie feststellen, ob eine nachfolgende unterdrückte Konvertierung erfolgreich ist - sie werden bei der Rückgabe von nicht berücksichtigtscanf()
.Verwenden Sie diese Option,
getchar()
bevor Sie den zweiten Anruf tätigenscanf()
.quelle
int c; while ((c = getchar()) != EOF && c != '\n') ;
(über drei Zeilen geschrieben, wenn kein Kommentar vorhanden ist). Es ist oft ausreichend; es ist nicht narrensicher (und man muss bedenken, dass Dummköpfe sehr klug sind, wenn es darum geht, Dinge zum Absturz zu bringen).