2012-03-17 10 views
18

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

Iは

int num=atoi(str); 

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

両方を試みたが、行の両方の文字列"8 -9 10"を送るこの文字列の無効を示すことなく、単に8を返さ。

誰にでも代替手段を提案できますか?

+0

'atoi'はエラーチェックを行いません。 'str'に' int'値の表現が含まれていない場合の動作は定義されていません。 (典型的な実装は '0'を返します。)' sscanf'はより優れていますが、文字列の値が 'int'として表現できない場合の動作は未定義です。また、あなたのタイトルは有効なintをチェックしたいと言っていますが、あなたの質問の本文には「有効な整数」と書かれています。彼らは同じことではありません。 'int'はいくつかの整数型の一つです。 –

答えて

29

strtol()を見ると、ポインタの戻り値によって文字列の無効な部分が分かります。

そして、熱狂的な例のコードに注意してください。総合的なエラー処理については、manページを参照してください。

+0

strtol()は、文字列の次の "オブジェクト"へのポインタを設定するだけです。それは何も検証しません。 –

+1

@ g24lそのポインタがNULLを指している場合、文字列全体が有効であることがわかります。そうでない場合、そうではありません。 Tadaa! – blueshift

+0

ヌル終了文字列の場合。 –

8

たぶん私は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; 
} 

[NB:私はそうisdigit(*str++)代わりのelseにを行っている可能性がありますそれを短くしておきますが、私の思い出は、isdigitがマクロである可能性があるという標準があると言うことです。]

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

+1

"それほど難しくないが、元に戻ってそれを変更しなければならなかった;) – blueshift

+1

@blueshiftポイントを取ったが、Webフォームにコードを入力すると5分で1回編集するのはそれほど難しくない。 :-) – asveikau

+0

この場合、自分自身をロールバックするのがエラーを起こしやすいか、strtol()のエラー処理を試みるのか分かりません。strtolをまだお勧めします。 – blueshift

2

int型の読み取りと作成するだろう確実にこれを行うための簡単な方法を確認してください、それは文字列表現は例がatoiitoaを結合するため、入力された文字列と同じですよ。

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

いいアイデア:)。しかし、これを有効にするには、先頭と末尾のスペースをトリムする必要があります。 – sara

+3

このソリューションはANSIに準拠していないことに注意してください。 –

0

文字列が含まれているかどうかをチェックするために正規表現を使用することができます。 [0-9] + [ -

[+]:? - [+] [0-9] +

と浮動小数点数のための一般的な場合

をたとえば整数で使用するための。]?[0-9] *([eE] [ - +]?[0-9] +)?

C++ 11の正規表現関数はライブラリで使用できます。 "std :: regex_match(.....)"は完全一致を返します。コードは次のようになります...トピックを掘り起こすために、しかし、完全を期すためとGoogle検索を行うときに、このスレッドは、最初に一致しているので、申し訳ありません

#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

をことが可能です以下のようなものを使用する:manページによると、標準Cのようです

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

%nディレクティブを、処理された文字の数をカウントします。

[編集] sscanfはオーバーフローを検出する方法を提供していないと思われるので、strtoXファンクションファミリを優先する必要があります。

関連する問題