Frage

Mit nur ANSI C, was der beste Weg ist, um mit ziemlicher Sicherheit, festzustellen, ob ein C-Stil-String entweder eine ganze Zahl oder eine reelle Zahl (das heißt float / double) ist?

War es hilfreich?

Lösung

Verwenden Sie atoi und atof nicht, da diese Funktionen 0 bei einem Fehler zurück. Als ich das letzte Mal überprüft 0 eine gültige ganze Zahl und Schwimmer, daher keine Verwendung für den Typ zu bestimmen.

verwenden, um die strto {l, UL, ull, ll, d} Funktionen, da diese errno auf Scheitern verurteilt, und auch berichten, wo die konvertierten Daten beendet.

strtoul: http://www.opengroup.org/onlinepubs/007908799/ xsh / strtoul.html

Dieses Beispiel geht davon aus, dass die Zeichenfolge einen einzelnen Wert enthalten umgewandelt werden.

#include <errno.h>

char* to_convert = "some string";
char* p = to_convert;
errno = 0;
unsigned long val = strtoul(to_convert, &p, 10);
if (errno != 0)
    // conversion failed (EINVAL, ERANGE)
if (to_convert == p)
    // conversion failed (no characters consumed)
if (*p != 0)
    // conversion failed (trailing data)

Dank Jonathan Leffler für den Hinweis auf, dass ich errno auf 0 zuerst einzustellen vergessen haben.

Andere Tipps

Mit sscanf , können Sie sicher sein, wenn die Zeichenfolge a float oder int oder was auch immer, ohne dass Sonderfall 0, wie es der Fall mit atoi und atof Lösung.

Hier ist ein Beispielcode:

int i;
float f;
if(sscanf(str, "%d", &i) != 0) //It's an int.
  ...
if(sscanf(str "%f", &f) != 0)  //It's a float.
  ...

atoi und atof konvertiert oder zurückgeben eine 0, wenn es nicht.

ich mit Patrick_O darüber einig, dass die strto {l, UL, ull, ll, d} Funktionen sind der beste Weg zu gehen. Es gibt ein paar Punkte, obwohl zu beobachten.

  1. Stellen Sie errno auf Null, bevor die Funktionen aufrufen; keine Funktion macht das für Sie.
  2. Die Seite Open Group verbunden (die ich ging, bevor sie merkt, dass Patrick auch mit ihm verbunden war) weist darauf hin, dass errno nicht gesetzt werden kann. Es wird auf ERANGE, wenn der Wert außerhalb des Bereichs liegt; es können gesetzt werden (aber gleich, können nicht gesetzt werden) auf EINVAL, wenn das Argument ungültig ist.

Je nach Job bei der Hand, ich werde manchmal arrangieren weißen Raum vom Ende der Umwandlung Zeiger zurück überspringen Hinter, und dann beschweren (ablehnen), wenn das letzte Zeichen nicht die abschließende Null ist ‚\ 0‘. Oder ich kann schlampig und lassen Müll am Ende erscheinen, oder ich kann optional Multiplikatoren wie ‚K‘ annehmen, ‚M‘, ‚G‘, ‚T‘ für Kilobyte, Megabyte, Gigabyte, Terabyte, ... oder jede andere Anforderung basierend auf dem Kontext.

Ich nehme an, Sie durch die Zeichenfolge Schritt könnte und prüfen, ob es in ihm keine . Zeichen sind. Das ist nur das erste, was allerdings in meinem Kopf auftauchte, so bin ich sicher, dass es andere (bessere) Möglichkeiten, um mehr sicher zu sein.

Mit strtol / strtoll (nicht atoi) ganzen Zahlen überprüfen. Verwenden Sie strtof / strtod (nicht atof) verdoppelt zu überprüfen.

atoi und atof den Anfangsteil der Zeichenfolge konvertieren, aber nicht sagen, ob sie alle die Zeichenfolge verwendet. strtol / strtod Ihnen sagen, ob es zusätzliche Junk, nachdem die Zeichen umgewandelt.

So in beiden Fällen erinnern in einem Nicht-Null-TAIL Parameter zu übergeben, und prüfen Sie, dass es bis zum Ende des Strings zeigt (das heißt, ** TAIL == 0). Überprüfen Sie auch den Rückgabewert für Unterlauf und Überlauf (siehe den Manpages oder ANSI-Standard für weitere Details).

Beachten Sie auch, dass strod / strtol Anfangs Leerzeichen überspringen, wenn Sie also Strings mit Anfangs Leerzeichen als schlecht formatiert behandeln möchten, können Sie auch das erste Zeichen überprüfen müssen.

Es hängt wirklich davon ab, warum Sie in erster Linie fragen.

Wenn Sie nur eine Nummer analysieren wollen, und wissen nicht, ob es ein Schwimmer oder eine ganze Zahl, dann analysieren nur einen Schwimmer, wird es richtig eine ganze Zahl analysiert als auch.

Wenn Sie tatsächlich die Art kennen, oder vielleicht für Triage wollen, dann sollten Sie wirklich die Typen in der Reihenfolge prüfen, testen, dass Sie die wichtigsten betrachten. Wie versuchen, eine ganze Zahl zu analysieren und wenn Sie nicht können, dann versuchen, einen Schwimmer zu analysieren. (Der andere Weg, um produziert nur ein wenig mehr Schwimmern ...)

atoi und atof wird die Zahl, auch wenn es nachlauf nicht numerische Zeichen umwandeln. Wenn Sie jedoch strtol verwenden und strtod es werden nicht nur Leerraum und ein optionales Zeichen überspringen führen, aber lassen Sie mit einem Zeiger auf das erste Zeichen, das nicht in der Zahl. Dann können Sie prüfen, ob der Rest Leerzeichen ist.

Nun, wenn Sie nicht das Gefühl, eine neue Funktion wie strtoul wie verwenden, können Sie einfach eine andere strcmp Anweisung hinzufügen, um zu sehen, wenn die Zeichenfolge 0 ist.

d.

if(atof(token) != NULL || strcmp(token, "0") == 0)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top