it-swarm.com.de

Bestimmen Sie, ob ein C-String ein gültiges int in C ist

Ich muss überprüfen, ob eine C-Zeichenfolge eine gültige ganze Zahl ist.

Ich habe beide probiert

int num=atoi(str);

und 

int res=sscanf(str, "%d", &num);

Das Senden des Strings "8 -9 10" in beiden Zeilen wurde jedoch einfach 8 zurückgegeben, ohne die Ungültigkeit dieses Strings anzuzeigen.

Kann jemand eine Alternative vorschlagen?

19
sara

Werfen Sie einen Blick auf strtol (), es kann Ihnen durch Zeigerrückgabe über ungültige Teile des Strings berichten.

Und hüten Sie sich vor enthusiastischem Beispielcode. Eine umfassende Fehlerbehandlung finden Sie in der Manpage.

30
blueshift

Vielleicht werde ich geflammt, weil ich strtol oder ähnliche libc-Funktionen nicht verwendet habe, aber es ist nicht so schwer, über dieses Problem nachzudenken.

#include <stdbool.h>  // if using C99...  for C++ leave this out.
#include <ctype.h>

bool is_valid_int(const char *str)
{
   // Handle negative numbers.
   //
   if (*str == '-')
      ++str;

   // Handle empty string or just "-".
   //
   if (!*str)
      return false;

   // Check for non-digit chars in the rest of the stirng.
   //
   while (*str)
   {
      if (!isdigit(*str))
         return false;
      else
         ++str;
   }

   return true;
}

[NB: Ich hätte vielleicht isdigit(*str++) anstelle der else getan, um es kürzer zu halten, aber meiner Erinnerung ist, dass die Standards sagen, dass isdigit möglicherweise ein Makro ist.

Eine Einschränkung ist vermutlich, dass dies nicht false zurückgibt, wenn die Zahl in der Zeichenfolge nicht in eine Ganzzahl passt. Das kann dir egal sein oder auch nicht.

8
asveikau

Eine einfache Möglichkeit, dies auf robuste Weise zu tun, wäre das Lesen des int und die Sicherstellung, dass seine Zeichenfolgendarstellung mit der Eingabezeichenfolge identisch ist, beispielsweise durch Kombinieren von atoi und itoa:

int is_int(char const* p)
{
    return strcmp(itoa(atoi(p)), p) == 0;
}
2
Inverse

Um zu überprüfen, ob die Zeichenfolge eine gültige Zahl enthält, können Sie einen regulären Ausdruck verwenden. Zum Beispiel für Ganzzahlen verwenden:

[- +]? [0-9] +

und ein allgemeiner Fall für Fließkommazahlen:

[+ -]? [0-9] + [.]? [0-9] * ([eE] [- +]? [0-9] +)?

Im Falle von C++ 11 sind reguläre Ausdrücke in der Bibliothek verfügbar, z. "std :: regex_match (.....)" gibt die genaue Übereinstimmung an. Der Code sollte so aussehen:

#include <regex>
.....
std::string strnumber("-1.234e+01");
float number;
if(regex_match(strnumber,std::regex("[+-]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?"))
number=std::stof(strnumber);
else
std::cout<<"error, string is not a valid number";
0
Kazik

Es tut uns leid, dass Sie das Thema ausgraben, aber der Vollständigkeit halber und weil dieser Thread der erste Treffer bei einer Google-Suche ist ...

Es ist möglich etwas zu verwenden:

ret = sscanf(string, "%d%n", &number, &idx);
if (ret == 0 || string[idx] != '\0')
    /* handle the error */

die %n-Direktive, die gemäß der Manpage standardmäßig C zu sein scheint, zählt die Anzahl der verarbeiteten Zeichen.

[Edit] sscanf scheint keine Möglichkeit zu bieten, Überläufe zu erkennen, daher sollte die strtoX-Funktionsfamilie IMHO bevorzugt werden.

0
ncarrier