2012-04-10 7 views
3

Ich möchte bestätigen, wenn ein von der Funktion scanf() zurückgegebener Wert eine Gleitkommazahl ist oder nicht. Wie kann ich das machen? Mein Code läuft nicht ordnungsgemäß, wenn die scanf() -Funktion falsche Datentypen enthält. Ähnlich wie würde ich bestätigen, wenn ein zurückgegebener Wert eine Zeichenkette ist oder nicht?Wie testen wir die Rückgabewerte der Funktion scanf()?

+0

Alle Versionen von 'scanf', die ich gesehen habe, gibt ein' int' zurück. – leppie

+1

@Saurabh Gehen Sie nach Ihrem vorherigen Qn, ich denke, Sie möchten wissen, ob scanf erfolgreich float_ gescannt hat und nicht _wenn sein Rückgabewert ein float_ ist, wie von Ihrer Frage angegeben? –

+3

Das Wichtigste, was Sie über die Funktionsfamilie '* scanf()' wissen sollten, ist, dass beim Scannen einer Zahl, deren Wert außerhalb der Grenzen des entsprechenden Typs liegt, das Verhalten nicht definiert ist. Wenn zum Beispiel 'scanf ("% d ")' versucht, '99999999999999999999999' zu lesen, kann alles passieren; Es gibt keine Möglichkeit, den Fehler zu behandeln. Es gibt keine gute Problemumgehung, außer etwas anderes als '* scanf()' zu verwenden, wie zum Beispiel die 'strto *()' Funktionen. –

Antwort

12

scanf() usw. geben die Anzahl der erfolgreichen Konvertierungen zurück.

Wenn Sie:

scanf("%f", &f); 

Sie sollten Test:

if (scanf("%f", &f) == 1) 
    ...all OK... 
else 
    ...EOF or conversion failure... 

Wenn Sie mehrere Konvertierungen haben, überprüfen Sie, dass sie alle abgeschlossen. Wenn Sie %n "Conversions" verwenden, werden diese nicht gezählt.

Obwohl scanf() EOF auf EOF zurückgibt, sollten Sie nicht für diese — testen Sie sollten immer in erster Linie überprüfen, dass Sie die Anzahl der erwarteten Konvertierungen erhalten haben. Betrachten wir zum Beispiel den Buggy Code:

while (scanf("%f %d %s", &f, &i, s) != EOF) // Here be BUGS! 
    ...loop body... 

Wenn Sie 3.14 x23 yes eingeben, dann werden Sie eine Endlosschleife, weil scanf() 1 bei der ersten Iteration zurück (es 3,14 erfolgreich umgesetzt) ​​und 0 danach (nicht EOF) .

Sie können in Ordnung sein mit:

while ((rc = scanf("%f %d %s", &f, &i, s)) != EOF) 
{ 
    if (rc != 3) 
     ...oops data problems... 
    else 
     ...all OK... 
} 

aus früheren Fragen zu urteilen, sollten Sie bei Verwendung fgets() suchen (oder möglicherweise POSIX getline()) Datenzeilen zu lesen, und dann sscanf() oder sogar Funktionen wie strtol() und strtod() zum Lesen bestimmter Werte aus der Zeile. Wenn Sie sscanf() verwenden, gelten die obigen Kommentare zur Überprüfung der Anzahl erfolgreicher Conversions weiterhin.

Ich verwende scanf() nicht im Produktionscode; es ist einfach zu verdammt schwer richtig zu kontrollieren. Ich betrachte es als fast geeignet für Anfangsprogramme —, außer dass es viel Verwirrung verursacht. Im Großen und Ganzen ist der beste Rat: Bleiben Sie frei von scanf() und fscanf(). Beachten Sie, dass dies nicht bedeutet, dass Sie sich von sscanf() fernhalten müssen, obwohl auch mit sscanf() etwas Vorsicht geboten ist.

+0

Awesome answer! Aber ich habe Zweifel: Will 'char a; scanf ("% c", &a); 'jemals null zurückgeben? –

+0

" isolated wie gezeigt, '"% c "' sollte nie 0 zurückgeben, weil entweder gibt es ein Zeichen zu lesen, so dass das Ergebnis 1 sein wird, oder nichts mehr zu lesen ist Das Ergebnis wird EOF sein, Sie müssen noch prüfen, welche dieser beiden Optionen zutrifft, und mit 'if (scanf ("% c ", & a) == 1) {... hat ein Zeichen ...}' ist immer noch richtig, was ist, was in der Hauptantwort empfohlen wird. –

5

Der Rückgabewert von scanf gibt die Anzahl der Elemente erfolgreich auf Ihre Variablen gelesen und zugeordnet, oder EOF:

Diese Funktionen die Anzahl der Eingabeelemente zurückgeben und zugewiesen erfolgreich angepasst, die weniger sein kann als vorgesehen oder sogar Null im Ereignis eines frühen Übereinstimmungsfehlers.

Der Wert EOF wird zurückgegeben, wenn das Ende der Eingabe erreicht wird, bevor entweder die erste erfolgreiche Konvertierung oder ein Übereinstimmungsfehler auftritt. EOF wird auch zurückgegeben, wenn ein Lesefehler auftritt, in diesem Fall wird die Fehleranzeige für den Strom (siehe ferror (3)) gesetzt, und errno wird gesetzt geben den Fehler an.

Wenn die zurück int von scanf einen Wert kleiner als die Menge des Eingangsbezeich hat (oder zumindest die Spezifizierer, die ein Argument erfordern weitergegeben werden) im Format-String, dann kann man etwas schief gelaufen nehmen.

Wenn Sie jedoch eine gründlichere Validierung Ihrer Fließkommazahl durchführen möchten, sollten Sie die Verwendung von strtod() in Erwägung ziehen. dh. für die Eingabe "1.23abc", scanf würde 1.23 in Ihrer Variablen speichern und Ihnen sagen, dass alles gut gelaufen ist, aber mit strtod können Sie überprüfen, ob das letzte konvertierte Zeichen tatsächlich das Ende der Zeichenfolge ist, die analysiert wird.

Verwandte Themen