2010-07-09 133 views
0

如果字符串中存在非數字字符,並且您調用atoi [我假設wtoi會執行相同的操作。 atoi如何處理字符串?字符串中的非整數和使用atoi

比方說一個例子,我有以下字符串:

  1. 「20234543」
  2. 「232B」
  3. 「B」

我敢肯定,1將返回整數20234543.我很好奇的是,如果2將返回「232」。 [這就是我需要解決我的問題]。另外3不應該返回一個值。這些信仰是錯誤的嗎?另外...如果2的確如我所相信的那樣行事,它如何處理字符串末尾的e字符? [這通常用於指數表示]

+6

爲什麼不試試看看? – Michael 2010-07-09 17:03:05

+1

我認爲社區會比建立一個支持unicode的新項目更快。 – monksy 2010-07-09 17:06:27

+3

「試着看」的作品,但它只顯示你的系統上的行爲。如果要確保代碼是可移植的,那麼閱讀標準是最好的方法。下面的大部分答案屬於「試看」,因此描述了atoi在某些系統上的工作原理。 – 2010-07-09 17:16:12

回答

4

你可以自己測試這種東西。我複製了Cplusplus參考站點的代碼。它看起來像你前兩個例子的直覺是正確的,但第三個例子返回'0'。在第二個例子中,'E'和'e'的處理就像'B'一樣。

所以規則是

成功時,該函數返回轉換的整數爲int值。 如果不能執行有效的轉換,則返回零值。 如果正確的值超出了可表示值的範圍,則返回INT_MAX或INT_MIN。

+1

-1。當輸入不能被表示爲整數時'atoi'的行爲是不確定的,所以你不能自己測試;任何調用未定義行爲的測試都是無效的。 Cplusplus.com並沒有說,但[cplusplus.com是一個臭名昭着的不可靠的參考](http://stackoverflow.com/q/6520052/33732)。你所引用的是'strtol'的規則,但適用於'int'而不是'long'(這意味着它們根本不適用於任何函數)。當您需要權威引用時,請使用該標準。當您需要快速參考時,請使用cppreference.com。 – 2014-07-10 15:46:12

+0

atoi()在「abc123」的輸入上返回0。爲什麼它被視爲0,但是當輸入「123abc」時,它顯示「123」作爲輸出。有人可以解釋這一點。 – 2016-08-09 16:27:38

+0

由於POSIX將'atoi'定義爲與處理前導空格(如果有)的'strtol'類似的行爲,所以數字,然後是任何無法識別的字符(如果有的話) (http://pubs.opengroup.org/onlinepubs /009695399/functions/strtol.html)。在你的第二個例子中,'strtol'擊中了無法識別的字符並放棄。 – gladed 2017-05-12 00:32:53

0

編寫簡單的代碼,並期待看到它做什麼是神奇和照亮。

在第3點,它不會返回「無」。它不能。它會返回一些東西,但是這對你不會有用。

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

成功時,該函數返回經轉換的整數爲int值。

如果無法執行有效的轉換,則返回零值。

如果正確的值超出了可表示值的範圍,則返回INT_MAX或INT_MIN。

+0

我知道它會返回0 [或設置值]或null。但我不確定。但我的問題是......是否轉換成下一個非整數值或什麼? – monksy 2010-07-09 17:05:56

+0

「下一個非整數值」是什麼意思? – 2013-05-31 17:06:32

+0

你是對的,它不能返回「無」,但這並不意味着它會返回「某物」。行爲是未定義的,所以它可能根本不會返回。 – 2014-07-10 15:53:47

2

atoi從字符串中讀取數字,直到它不能再更多。當它遇到任何不是數字的字符時,它將停止,除了空格(它跳過)或'+'或' - '之外的任何數字(它用於爲結果選擇適當的符號) 。如果看不到數字,它將返回0。

所以要回答你的具體問題:1返回20234543. 2返回232. 3返回0.字符'e'不是空格,數字,'+'或' - ',所以atoi停止並返回,如果它遇到那個角色。請參閱here

2

如果atoi遇到一個非數字字符,它將返回到該點爲止形成的數字。

8

根據標準,「功能atofatoiatolatoll不必影響上一個錯誤的整數表達式errno的值。如果結果的值不能表示,該行爲是未定義」。 (7.20.1,在C99中的數字轉換函數)。

因此,從技術上講,任何事情都可能發生。即使對於第一種情況,由於INT_MAX保證至少爲32767,並且由於20234543大於此值,所以它也可能失敗。

爲了更好的錯誤檢查,使用strtol

const char *s = "232B"; 
char *eptr; 
long value = strtol(s, &eptr, 10); /* 10 is the base */ 
/* now, value is 232, eptr points to "B" */ 

s = "20234543"; 
value = strtol(s, &eptr, 10); 

s = "123456789"; 
value = strtol(s, &eptr, 10); 
/* If there was no overflow, value will contain 123456789, 
    otherwise, value will contain LONG_MAX and errno will be ERANGE */ 

如果您需要在他們的「e」(指數形式)來解析號碼,那麼你應該使用strtod。當然,這些數字是浮點數,並且strtod返回double。如果你想從中得到一個整數,你可以在檢查正確的範圍後進行轉換。

+0

失敗,但根據MSDN整數是32位。 http://msdn.microsoft.com/en-us/library/296az74e.aspx – monksy 2010-07-09 17:15:14

+0

@steven:它還在頂部顯示「Microsoft Specific」。所以如果你只關心微軟特定的代碼,那麼你是對的,你不需要擔心第一種情況的溢出。但是如果你想要可移植性,你需要。你的問題沒有用任何平臺特定的標籤標記,所以我假設你想要可移植性:-)。 – 2010-07-09 17:19:51

+0

夠公平的。我寫的大部分系統都是32位的,所以我習慣了。 [16位是很久以前] – monksy 2010-07-09 17:31:56