簡體   English   中英

將字符串轉換為數字

[英]Converting string to a number

我遇到了這個C程序:

int main() {
    printf("Enter your address, (e.g. 51 Anzac Road) ");
    gets(address);
    number = 0;
    i = 0;
    while (address[i] != ' ') {
        number = number * 10 + (address[i] - 48);
        i++;
    }
}

我知道number = number * 10 + (address[i] - 48); 是從輸入中獲取數字,但是有人可以向我解釋這是如何工作的嗎? 如何從輸入中產生數字?

在ASCII中,數字字符 '0''9'占據代碼點48至57(i hex, 0x300x39 ),因此,要將數字字符轉換為值,只需減去48。


順便說一句,您確實應該減去'0'因為該標准不保證ASCII,盡管它確實保證了數字字符是連續且有序的。 例如,z / OS下的C使用EBCDIC,它將數字放置在代碼點0xf00xf9


循環本身是一種簡單的移位加法類型,可以從多個數字字符中創建一個數字。 假設您有字符串"123" ,且number最初為零。

number (零)乘以10得到零,然后加上數字字符'1' (49)並減去48。這得到一個。

然后,將number (一)乘以十得到十,並加上數字字符'2' (50),再減去48。這便得出十二。

最后,將number (十二)乘以十得到一百二十,然后加上數字字符'3' (51)並減去48。這將得出一百二十三。

在C標准庫, atoi或更強大的strtol型函數中,有更好的方法可以在stdlib.h找到它們。 后者使您可以更好地檢測數字末尾是否有“垃圾”,以幫助進行驗證( atoi無法分辨123123xyzzy之間的區別)。


而且,除其他外,您應該避免像瘟疫一樣使用gets() 就像“ naked” scanf("%s") ,它不適合用戶輸入,並打開您的代碼以緩沖溢出問題。 實際上,與scanf()不同, 沒有安全的方法可以使用gets() ,這無疑就是為什么將其從最新標准C11中刪除的原因。 可以在此處找到更強大的用戶輸入功能。

還有一大類地址,該代碼將嚴重地失敗,例如:

3/28 Tivoli Rd
57a Smith Street
Flat 2, 12 Xyzzy Lane

C要求將數字09以此順序連續存儲在執行字符集中。 48是ASCII值'0' ,因此,例如:

'3' - 48 == 3

對於任何數字。

C不需要ASCII,因此更好的是:

'3' - '0' 

因為雖然48對ASCII是正確的,但從定義上來說, '0'對任何字符集都是正確的。

如果address包含"456 " ,則:

  • i == 0number == 0number * 10 + (address[0] - 48)等於0 * 10 + 44
  • i == 1number * 10 + (address[1] - 48)4 * 10 + 545
  • i == 2number * 10 + (address[2] - 48)45 * 10 + 6456

到此為止。

永遠不要使用gets() ,這很危險,甚至不再是C的一部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM