web-dev-qa-db-ja.com

C文字列がCで有効なintかどうかを判別

C文字列が有効な整数かどうかを確認する必要があります。

両方試しました

int num=atoi(str);

そして

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

しかし、文字列"8 -9 10"両方の行で、この文字列が無効であることを示すことなく、単に8行を返しました。

誰かが代替案を提案できますか?

19
sara

Strtol()を見てください。ポインタの戻りによって、文字列の無効な部分がわかります。

また、熱心なサンプルコードには注意してください。包括的なエラー処理については、manページを参照してください。

30
blueshift

多分私はstrtolや類似のlibc関数を使わないことに怒るでしょうが、この問題についての推論はそれほど難しくありません:

_#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;
}
_

[注:短くするためにelseの代わりにisdigit(*str++)を実行した可能性がありますが、私の記憶によると、規格ではisdigitはマクロである可能性があるとしています。]

文字列の数値が整数に収まらない場合、これはfalseを返さないという制限があると思います。それはあなたにとって重要かもしれないし、重要ではないかもしれません。

7
asveikau

これを確実に行う簡単な方法は、intを読み取り、その文字列表現が入力文字列と同一であることを確認することです。たとえば、atoiitoaを組み合わせます。

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

文字列に有効な数値が含まれているかどうかを確認するには、正規表現を使用できます。たとえば、整数の場合は次のようにします。

[-+]?[0-9] +

浮動小数点数の一般的なケース:

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

C++ 11の場合、ライブラリで正規表現関数を使用できます。 "std :: regex_match(.....)"は完全一致を示します。コードは次のようになります。

#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

トピックを掘り下げて申し訳ありませんが、完全を期すため、およびこのスレッドはグーグル検索を行うときの最初の一致なので...

次のようなものを使用することが可能です:

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

%nディレクティブは、manページによれば標準Cのようですが、処理された文字数をカウントします。

[[編集] sscanfはオーバーフローを検出する方法を提供していないようです。そのため、strtoX関数ファミリを優先する必要があります。

0
ncarrier