[英]Non-Integer numbers in an String and using atoi
如果字符串中有非數字字符並且您調用 atoi [我假設 wtoi 也會這樣做]。 atoi 將如何處理字符串?
舉個例子,我有以下字符串:
我確定 1 會返回整數 20234543。我很好奇 2 是否會返回“232”。 [這就是我需要解決的問題]。 另外 3 不應返回值。 這些信念是錯誤的嗎? 另外...如果 2 確實像我所相信的那樣,它如何處理字符串末尾的 e 字符? [通常用於指數表示法]
根據標准,“函數atof
、 atoi
、 atol
和atoll
不需要在錯誤時影響整數表達式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 = "123456789012345";
value = strtol(s, &eptr, 10);
/* If there was no overflow, value will contain 123456789012345,
otherwise, value will contain LONG_MAX and errno will be ERANGE */
如果您需要解析其中包含“e”的數字(指數表示法),那么您應該使用strtod
。 當然,這樣的數字是浮點數, strtod
返回double
。 如果你想從中得到一個整數,你可以在檢查正確的范圍后進行轉換。
你可以自己測試這種事情。 我從Cplusplus參考站點復制了代碼。 看起來您對前兩個示例的直覺是正確的,但第三個示例返回 '0'。 'E' 和 'e' 的處理方式與第二個示例中的 'B' 一樣。
所以規則是
成功時,該函數將轉換后的整數作為 int 值返回。 如果無法執行有效轉換,則返回零值。 如果正確值超出可表示值的范圍,則返回 INT_MAX 或 INT_MIN。
atoi
從緩沖區讀取數字,直到不能再讀取為止。 當它遇到任何不是數字的字符時停止,除了空格(它跳過)或“+”或“-”,然后才能看到任何數字(它用於為結果選擇適當的符號) . 如果沒有看到數字,則返回 0。
因此,要回答您的具體問題:1 返回 20234543。2 返回 232。3 返回 0。字符 'e' 不是空格、數字、'+' 或 '-',因此 atoi 會在遇到該字符時停止並返回。
另請參見此處。
如果 atoi 遇到一個非數字字符,它會返回在該點之前形成的數字。
我嘗試在一個項目中使用 atoi() ,但如果混合中有任何非數字字符並且它們出現在數字字符之前,它將不起作用 - 它會返回零。 無論出於何種原因,它們是否出現在數字之后似乎都不介意。
這是我寫的一個非常簡單的字符串到 int 轉換器,它似乎沒有這個問題(簡單的原因是它不適用於負數並且它沒有包含任何錯誤處理,但它可能有助於具體情況)。 希望它可能會有所幫助。
int stringToInt(std::string newIntString)
{
unsigned int dataElement = 0;
unsigned int i = 0;
while ( i < newIntString.length())
{
if (newIntString[i]>=48 && newIntString[i]<=57)
{
dataElement += static_cast<unsigned int>(newIntString[i]-'0')*(pow(10,newIntString.length()-(i+1)));
}
i++;
}
return dataElement;
}
當我學習接近編碼程序時,我將自己歸咎於這種 atoi 函數行為,該程序具有通過啟動命令行參數來計算給定輸入參數的整數階乘結果的函數。
如果 value 不是數字值,atoi-function 返回 0,並且“3asdf”返回 3。C 語言處理 char -array 指針變量中的命令行輸入參數,眾所周知。
有人告訴我,在“Linux Hater's Handbook”一書中,有一些對計算機極客有吸引力的討論並不真正喜歡 atoi 函數,因為無法檢查給定輸入類型的有效性,這有點愚蠢。
有人問我為什么我不兄弟使用位於 stdlib.h -library 上的 strtol 函數,他給了我一個附加到我的階乘計算遞歸方法的示例,但我不在乎階乘結果大於整數主類型值 - 范圍,超出范圍(基數太大)。 這將導致我的程序中出現負值。
我用 atoi 函數解決了我的問題,首先檢查給定用戶的輸入參數是否真的是數值,如果匹配,然后我計算階乘值。
使用位於 chtype.h -library 上的 isdigit() -function 如下:
int checkInput(char *str[]) {
for (int x = 0; x < strlen(*str); ++x)
{
if (!isdigit(*str[x])) return 1;
}
return 0;
}
我在其他 Linux 編程論壇上的論壇朋友告訴我,如果我使用 strtol,我可以處理值超出范圍的情況,甚至可以將 signed int 解析為 unsigned long 類型,這意味着 -0 和其他負值不被接受。
如果字符不是數值,在我的代碼檢查上很重要。 檢查此函數的協商方式,當第一個數值出現在檢查字符串的下一個時,該函數返回失敗的結果。 (或 C 中的字符數組)
編寫簡單的代碼並觀察它的作用是神奇而富有啟發性的。
在第 3 點上,它不會返回“什么都沒有”。 它不能。 它會返回一些東西,但那些東西對你沒有用。
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
成功時,該函數將轉換后的整數作為 int 值返回。
如果無法執行有效轉換,則返回零值。
如果正確值超出可表示值的范圍,則返回 INT_MAX 或 INT_MIN。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.