2012-03-17 154 views
18

我需要檢查C字符串是否爲有效整數。確定C字符串是否爲C中的有效整數

我都嘗試

int num=atoi(str); 

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

但在這兩個線路的發送串"8 -9 10"只需8返回,沒有說明這個字符串的無效性。

任何人都可以提出一個替代方案嗎?

+0

'atoi'沒有錯誤檢查;它的行爲如果'str'不包含'int'值的表示是未定義的。 (典型實現返回'0'。)'sscanf'更好,但是如果字符串中的值不能表示爲int,那麼它的行爲是不確定的。此外,你的標題說你想檢查一個有效的整數,但你的問題的正文說「有效的整數」;他們不是一回事。 'int'是幾個* integer *類型之一。 – 2012-03-18 00:22:50

回答

29

看看strtol(),它可以通過指針返回來告訴你關於字符串的無效部分。

並提防熱情的示例代碼..請參閱手冊頁以獲取全面的錯誤處理。

+0

strtol()只是將指針設置爲字符串中下一個「對象」。它不驗證任何內容。 – 2012-03-17 20:41:31

+1

@ g24l如果該指針最終指向NULL,那麼你知道整個字符串是有效的。如果沒有,不是。 Tadaa! – blueshift 2012-03-17 20:45:35

+0

如果它是一個以空字符結尾的字符串。 – 2012-03-17 20:47:36

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

[注:我可能會做,否則的isdigit(*str++)代替else到保持它更短,但我的回憶是,標準說isdigit是一個宏。]

我想一個限制是,如果字符串中的數字不適合整數,這不會返回false。這對你而言可能並不重要。

+1

「不那麼難」,但你必須回來改變它;) – blueshift 2012-03-17 20:52:57

+1

@blueshift採取點,但1編輯輸入代碼到Web表單5分鐘對我來說並不壞。 :-) – asveikau 2012-03-17 20:54:30

+0

在這種情況下,我不知道是否更容易出錯或者嘗試獲取strtol()的錯誤處理。我可能還會推薦strtol。 – blueshift 2012-03-17 20:57:12

2

一個簡單的方法來做到這一點有力將讀取int和確保它的字符串表示是相同的輸入字符串,例如結合atoiitoa

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

好主意:)。但是,這也需要修剪前後空格,以使其工作。 – sara 2012-03-21 08:55:47

+3

請注意,此解決方案不符合ANSI標準。 – 2013-04-26 22:55:55

0

對於檢查是否字符串包含您可以使用正則表達式的有效數字。例如,對於使用整數:

[ - +] [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

對不起,我挖的話題,但爲了完整起見,因爲這個線程是做了谷歌搜索時的第一場比賽...

有可能使用類似:

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

%n指令,這似乎根據手冊頁是標準的C,計算處理的字符數。

[編輯] sscanf的似乎沒有提供一種方法來檢測溢出,所以strtoX函數族應首選IMHO。