2016-03-22 24 views
1

Hier ist mein Code zum wiederholten Lesen drei Variablen durch Leerzeichen vom Benutzer getrennt. Das Eingabeformat sollte 'char int int' sein (z. B. b 3 3). Ich verwende den Rückgabewert der scanf-Funktion, um sicherzustellen, dass die Eingabe genau drei Variablen ist.Rückgabewert von scanf()

#include <stdio.h> 

int main(void){ 
    int x, y, nargs; 
    char command; 

    while(1){ 
    nargs = scanf("%c %d %d", &command, &x, &y); 
    printf("%d\n",nargs); 

    if(nargs != 3){ 
     printf("error\n"); 
     break; 
    } 
    } 
    return 0; 
} 

Eingang und Ausgang:

g 4 4 
3 
b 3 3 
1 
error 

Die erste Zeile eingegeben wird, kein Problem. Aber wenn ich die zweite Zeile eingabe, zeigt scanf() nur eine Variable aus dieser Zeile. Was ist das Problem meines Codes?

+3

'"% c% d% d "' ist die schnelle Antwort. Mit 'fgets()' und dann 'sscanf (buf,"% c% d% d ", ...' ist besser. GTG – chux

Antwort

2

Das Problem ist dieNewline zwischen den beiden Eingabezeilen versteckt, die Sie an Stdin senden. Nach dem ersten scanf haben Sie eine '\n' ausstehend für den Eingangsstrom, dann fügen Sie "b 3 3" an, so dass der gesamte Puffer wie "\nb 3 3" aussieht.

Dann wird scanf erneut aufgerufen und \n auf %c angepasst, nachdem scanf Leerzeichen erwartet, aber der Puffer 'b' so schlägt es nach \n zu command zuweisen.

könnten Sie passende versuchen mit

nargs = scanf("%c %d %d ", &command, &x, &y); 
        ^

so dass Newline mit dem vorherigen scanf gegessen wird, von cppreference:

jede einzelne Leerzeichen im Formatstring verbraucht alle verfügbaren aufeinanderfolgenden Leerzeichen aus der Eingang

+0

Got it! Aber es gibt ein neues Problem, es kann nicht lesen meine erste Zeile Eingabe. Ich sollte dann g 4 4 \ nb 3 3 \ n dann die Programmrückmeldung 3 eingeben. –

+1

Verwende '"% c% d% d "' nicht '"% c% d% d "' Am Anfang benötigter Platz hat Probleme – chux

-2
nargs = scanf("%1s %d %d", &command, &x, &y); 

Das Problem ist mit dem %c für ein Zeichen. Wenn Sie es für %1s ändern, erwarten Sie eine Zeichenfolge eines Zeichens (das gleiche) aber ohne Probleme.

Mit der %c ist es besser, das Ergebnis an ein Array zu senden und den Inhalt mit seinem Index zugreifen.

+1

'"% 1s "' ist eine schlechte Idee mit 'Char Befehl;' - Pufferüberlauf. – chux

+2

Um @ chux Kommentar zu erweitern, liest '% 1s' in eine ein Zeichen * string *, die zwei Bytes belegt eine für die Daten und eine für den Terminator "\ 0". –