Ermitteln Sie, ob eine Zeichenfolge in ANSI C eine Ganzzahl oder ein Gleitkomma ist

8

Mit nur ANSI C, was ist der beste Weg, um mit einiger Sicherheit festzustellen, ob eine C-Stil-String ist entweder eine ganze Zahl oder eine reelle Zahl (d. h. float / double)?

    
Christopher Dolan 16.09.2008, 23:55
quelle

9 Antworten

34

Verwenden Sie nicht atoi und atof, da diese Funktionen bei einem Fehler 0 zurückgeben. Das letzte Mal, als ich 0 überprüfte, ist eine gültige Ganzzahl und float, daher keine Verwendung zur Bestimmung des Typs.

Verwenden Sie die Funktionen strto {l, ul, ull, ll, d}, da diese beim Auftreten eines Fehlers die Fehlernummer festlegen und auch melden, wo die konvertierten Daten enden.

Ссылка

In diesem Beispiel wird davon ausgegangen, dass die Zeichenfolge einen einzelnen zu konvertierenden Wert enthält.

%Vor%

Danke an Jonathan Leffler für den Hinweis, dass ich vergessen habe, zuerst errno auf 0 zu setzen.

    
Patrick_O 17.09.2008, 00:11
quelle
9

Mit sscanf können Sie sicher sein, ob die Zeichenfolge ein Float oder ein int oder was auch immer ist ohne Sonderfall 0 zu haben, wie es bei Atoi und Atof-Lösung der Fall ist.

Hier ist ein Beispielcode:

%Vor%     
Patrick 17.09.2008 00:13
quelle
3

atoi und atof konvertieren oder geben eine 0 zurück, wenn nicht.

    
itsmatt 16.09.2008 23:58
quelle
3

Ich stimme Patrick_O zu, dass die Funktionen von strto {l, ul, ull, ll, d} der beste Weg sind. Es gibt jedoch ein paar Punkte zu beachten.

  1. Setze errno vor dem Aufruf der Funktionen auf Null; Keine Funktion macht das für dich.
  2. Die Open-Group-Seite, mit der ich verlinkt bin (die ich besucht habe, bevor ich bemerkt habe, dass Patrick mit ihr verbunden war), weist darauf hin, dass errno möglicherweise nicht gesetzt ist. Es wird auf ERANGE gesetzt, wenn der Wert außerhalb des zulässigen Bereichs liegt. es kann gesetzt werden (aber ebenso, darf nicht gesetzt sein), wenn ein Argument ungültig ist, auf EINVAL.

Abhängig von der jeweiligen Aufgabe arrangiere ich manchmal, dass am Ende des zurückgegebenen Konvertierungszeigers übergehender Leerraum übersprungen wird, und beschwere mich dann (ablehnen), wenn das letzte Zeichen nicht der abschließende Nullwert '\ 0' ist. Oder ich kann schlampig sein und Müll am Ende erscheinen lassen, oder ich kann optionale Multiplikatoren wie 'K', 'M', 'G', 'T' für Kilobyte, Megabyte, Gigabyte, Terabyte, ... oder andere akzeptieren Anforderung basierend auf dem Kontext.

    
Jonathan Leffler 17.09.2008 07:14
quelle
2

Ich nehme an, Sie könnten durch die Zeichenfolge gehen und prüfen, ob . Zeichen darin enthalten sind. Das ist aber nur das Erste, was mir in den Sinn kam, also bin ich sicher, dass es andere (bessere) Wege gibt, um sicherer zu sein.

    
nutbar 16.09.2008 23:58
quelle
2

Verwenden Sie strtol / strtoll (nicht atoi), um Ganzzahlen zu prüfen. Verwenden Sie strtof / strtod (nicht atof), um Doubles zu prüfen.

atoi und atof konvertieren den Anfangsteil des Strings, sagen aber nicht, ob sie den gesamten String verwendet haben oder nicht. strtol / strtod sagt dir, ob es nach der Umwandlung der Charaktere zusätzlichen Müll gegeben hat.

Denken Sie also in beiden Fällen daran, einen TAIL-Parameter ungleich Null zu übergeben, und prüfen Sie, ob er auf das Ende der Zeichenfolge zeigt (also ** TAIL == 0). Überprüfen Sie auch den Rückgabewert für Unterlauf und Überlauf (Details finden Sie in den Manpages oder im ANSI-Standard).

Beachten Sie auch, dass strod / strtol den anfänglichen Whitespace überspringt. Wenn Sie also Strings mit initialem Whitespace als schlecht formatiert behandeln möchten, müssen Sie auch das erste Zeichen überprüfen.

    
Steve Jessop 17.09.2008 00:21
quelle
1

Es hängt wirklich davon ab, warum Sie zuerst fragen.

Wenn Sie nur eine Zahl analysieren wollen und nicht wissen, ob es sich um einen Gleitkommawert oder eine Ganzzahl handelt, dann parsen Sie einfach einen Gleitkommawert und parsen eine Ganzzahl korrekt.

Wenn Sie den Typ wirklich kennen möchten, zum Beispiel für die Triage, sollten Sie wirklich überlegen, die Typen in der Reihenfolge zu testen, die Sie für am relevantesten halten. Versuchen Sie beispielsweise, eine Ganzzahl zu analysieren, und wenn Sie nicht können, dann versuchen Sie, einen Gleitkommawert zu analysieren. (Andersherum werden nur ein paar mehr Floats produziert ...)

    
Vincent Robert 17.09.2008 00:07
quelle
1

atoi und atof werden die Zahl selbst dann konvertieren, wenn nicht numerische Zeichen folgen. Wenn Sie jedoch strtol und strtod verwenden, wird nicht nur der führende Leerraum und ein optionales Zeichen übersprungen, sondern Sie erhalten einen Zeiger auf das erste Zeichen, das nicht in der Zahl enthalten ist. Dann können Sie überprüfen, ob der Rest Leerzeichen ist.

    
Russ Ryan 17.09.2008 00:12
quelle
0

Nun, wenn Sie keine neue Funktion wie strtoul verwenden möchten, können Sie einfach eine weitere strcmp-Anweisung hinzufügen, um zu sehen, ob die Zeichenfolge 0 ist.

d. h.

%Vor%     
Katie 15.02.2014 00:41
quelle

Tags und Links