2016-11-11 11 views
4

Ich frage nur, was macht der getchar in diesem Code und wie funktioniert es? Ich verstehe nicht, warum der getchar den Code beeinflusst, für mich scheint es, als würde er nur den Wert bekommen, aber nichts wird mit dem Wert gemacht.C-Code, scanf und getchar

+2

Hinweis: Versuchen Sie mit 'char' Typ. Hier ist es überflüssig. –

+0

perfekt danke – james

Antwort

0

Wahrscheinlich ist der Code zum Lesen in einer Liste von ganzen Zahlen, getrennt durch eine neue Zeile.

scanf liest eine ganze Zahl ein und fügt sie in die Variable c ein.

Die getchar wird im nächsten Zeichen zu lesen (eine neue Zeile unter der Annahme)

Da es nicht überprüfen, gibt es ein gewisses Potenzial, dass es nicht eine neue Linie, oder dass scanf war als das, was es ist fehlgeschlagen versucht zu lesen war keine Nummer.

3

Einige Möglichkeiten, warum getchar() dort verwendet worden sein könnte:

1) Wenn es Leerzeichen gemacht wird (in der Regel verwendet, um zu ignorieren, wenn Zeichen mit %c) abgetastet wird, ist es hier nicht notwendig, weil %d Whitespaces ohnehin ignoriert.

2) Eine andere Möglichkeit ist, dass nach diese Schleife, einige weitere Prüfung erfolgt, wo die letzte \n durch den letzten Aufruf von links nach scanf() könnte ein Problem sein. Also, getchar() könnte verwendet werden, um es zu ignorieren.

3) Wenn Sie Zeichen eingeben, die nicht mit %d übereinstimmen, schlägt scanf() fehl. Da die eingegebenen Zeichen im Eingabestream verbleiben, können Sie nie wieder eine int lesen (wenn Sie beispielsweise abcdddgdfg ohne diesen getchar()-Aufruf eingeben). Also, getchar() Hier werden alle diese Zeichen (ein pro Iteration) verbrauchen und schließlich können Sie int (mit %d) wieder lesen.

Aber das ist alles wirklich nicht nötig; es ist nur ein Versuch, Fehler von scanf() zu beheben. Lesen von Eingaben mit scanf() und bekommen es richtig ist wirklich schwierig. Aus diesem Grund wird empfohlen, fgets() zu verwenden und die Funktionen sscanf() oder strto*() zu analysieren, wenn Sie nur Ganzzahlen scannen.

See: Why does everyone say not to use scanf? What should I use instead?

+0

Gute Punkte und Schlussfolgerung. – chux

1

In diesem Code ist getchar für seine Nebenwirkungen genannt wird: es ein Zeichen von der Standardeingabe liest und wirft sie weg.

Wahrscheinlich liest dies die Eingabe des Benutzers. scanf wird eine Nummer konsumieren, aber das Newline-Zeichen nach der Nummer unverändert lassen. Die getchar verbraucht den Zeilenumbruch und wirft ihn weg. Dies ist in dieser Schleife nicht unbedingt erforderlich, da die nextscanf Whitespaces überspringt, um die nächste Zahl zu finden, aber es könnte nützlich sein, wenn der Code nach nicht erwartet, dass ein Zeilenumbruch als erstes erwartet wird Ding auf stdin.

Dieser Code ist fehlerhaft, weil es nicht für EOF nicht überprüfen, weil es nicht alles sinnvoll macht, wenn der Eingang nicht eine Zahl oder wenn gibt es mehr Text auf der Linie nach der Zahl, und weil es verwendet scanf, die wie angegeben zerlegt ist (zum Beispiel ist es erlaubt, crash das Programm, wenn der Eingang überläuft den Bereich von int). Bessere Code wäre so etwas wie

char *linep = 0; 
size_t asize = 0; 
char *endp; 
long c; 
while (getline(&linep, &asize, stdin) > 0) { 
    errno = 0; 
    c = strtol(linep, &endp, 10); 
    if (linep == endp || *endp != '\0' || errno) { 
     puts("?Redo from start"); 
     continue; 
    } 
    if (c == 0) break; 
    do_something_with(c); 
} 
free(linep); 
0

getchar(); einfach sein liest und konsumieren die Zeichen nach der Zahl, sei es ein Leerzeichen, Komma, neue Zeile oder den Beginn einer anderen ganzen Zahl oder irgendetwas anderes.

IMO, das ist kein robuster Code. Guter Code würde 1) zumindest das Ergebnis von scanf() testen und 2) den Verbrauch des folgenden Zeichens testen oder begrenzen, um zu verhindern, dass ein potentielles Zeichen der folgenden Zahl "gefressen" wird. Erinnern Code kann nicht kontrollieren, was ein Benutzer eingibt, sondern muss mit allem umgehen, was eingegeben wird.

v space 
"123 456" 

    v comma 
"123,456" 

    v negative sign 
"123-456"