2014-02-10 43 views
0

所以我有這樣的代碼:將char數組轉換爲(負)整數;不編譯,因爲「陣列 - ‘0’」的行

#include <stdio.h> 

int main(void) { 
    char arr[BUFSIZ]; 
    arr[BUFSIZ - 1] = '\0'; 
    fgets(arr, sizeof(arr), stdin); 
    int x = arr - '0'; 
    printf("%d\n", x); 
} 

,當我嘗試編譯它,用鏗鏘的化妝,我得到這個錯誤:

$ make test 
clang -ggdb3 -O0 -std=c99 -Wall -Werror test.c -lm -o test 
test.c:9:9: error: incompatible pointer to integer conversion initializing 'int' 
     with an expression of type 'char *' [-Werror,-Wint-conversion] 
    int x = arr - '0'; 
     ^ ~~~~~~~~~ 
1 error generated. 

如果我評論或取消對arr[BUFSIZ - 1] = '\0';線不要緊,這只是將不編譯。

我讀過int x = arr - '0';應該做的伎倆,但它沒有..

+0

'arr [0] - '0''? – timrau

+0

目前還不清楚,你正在嘗試做什麼。 int x =(int)arr - '0'不應該產生任何錯誤,但我很難確定這是否是預期的行爲。 arr [0] - '0'會給你輸入的第一個數字。 – dureuill

+0

謝謝,現在的作品,但不lil'bit理所應當: 'jharvard @電器(〜/ CS50/PSET1):./test 輸入:-123 輸出:-3' 'jharvard @家電(〜/ CS50/pset1):./test 輸入:123 輸出:1' 爲什麼在負數的情況下?它應該返回第一位,而不是最後一位。 – spaffy

回答

1

您的方案的預期用戶輸入是代表數字字符的字符串,可能與一個減號作爲前綴。

假設在第一個用戶給出了一個預期的輸入。

該輸入被存儲在大小尺寸的字符數組:

char arr[SIZE]; 
fgets(arr, SIZE, stdin); 

此時,您的陣列ARR成立,其中的陣列的內容駐留的地址(用於爲例0xDA7A1234)。如果您嘗試在arr中獲取值,則需要使用[]運算符。 這就是爲什麼你的int x = arr - '0'不起作用。它採用arr中的地址,然後用char'0'(這與減去48相同)減去它。

比方說,你輸入 '4' '5' '6' '7'。 arr等於0xDA7A1234,arr [0](即0xDA7A1234)等於'4',arr [1](0xDA7A1235)等於'5',依此類推。 '4'是一個ASCII字符。它是一個字符的表示,但對C來說它只是一個數字值。 ascii表是一個標準,它給出了給定字符的匹配數值(這裏是一個ascii表:http://www.asciitable.com/index/asciifull.gif)。 在這個表中,匹配'4'的十進制值是52.匹配'0'的十進制值是48.所以'4' - '0'實際上只是52 - 48 = 4。由於ascii表中的數字是連續的,用'0'字符減去一個數字字符會給你(或者說我現在不設計的)通過整數表示的正確數字。但是,如果存在減號(例如' - ''1''2''4'),您將執行的操作是'-' - '0',根據ASCII表格,它確實是45 - 48,它產生-3觀察到(與您的輸入包含3作爲最後一位數字無關)。

這意味着你必須做出的一個特例「 - 」字符。例如:

char is_negative = 0; // 0 means that it is a positive integer, 
         // 1 a negative integer 
if (arr[0] == '-') { 
    is_negative = 1; 
} 
// ... We retrieve the other digits in x 
if (is_negative == 1) { 
    x *= -1; // Let's make x a negative integer 
} 

有了這個整理出來,你需要一種方法來實際檢索其他數字(你不能只使用第一位的,尤其是如果它只是一個「 - 」)。

要做到這一點,你需要看看你陣列中的每個字符,使用循環。

int i; 
for (i = 1; i < SIZE; ++i) { 
     int digit = arr[i] - '0'; 
     x *= 10; // shift x by a power of ten 
     x += digit; // add the newly retrieved digit. 
} 

上面的循環存在問題。事實上,你的用戶可能會輸入一個沒有SIZE-1位數的整數。那麼會發生什麼?程序將在arr中查找未初始化的值,這意味着它們將隨機出現(它們的值不是由C標準定義的,因此可能是任何東西)。即使你的數組​​有最大長度,一個C字符串也是null結尾的,這意味着字符'\ 0'在數組的末尾,所以無論如何它都會搞亂。

爲了解決這個問題,我們需要獲得數組的實際「有用」大小,即字符串長度。 爲了實現這一點,我使用了字符串函數strlen,它返回字符串的長度而不計算空終止字符('\ 0')。

// let's get the actual size of the array 
size_t len = strlen(arr); 

// our loop becomes 
for (i = 1; i < len; ++i) { 
    int digit = arr[i] - '0'; 
    x *= 10; // shift x by a power of ten 
    x += digit; // add the newly retrieved digit. 
} 

但是,仍然存在一個錯誤。事實上,我們的字符串包含一個隱藏的角色,可以被計算!當您按回車鍵確認您的輸入時,新行字符'\ n'被添加到行中(十進制ASCII碼10)。你不想這樣,所以正確的循環是:

for (i = 1; i < len-1; ++i) { 
    int digit = arr[i] - '0'; 
    x *= 10; // shift x by a power of ten 
    x += digit; // add the newly retrieved digit. 
} 

注意的len-1

所以,這裏將是你的完整的例子:

#define SIZE 8 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
int main(void) { 
    char arr[SIZE]; 
    fgets(arr, SIZE, stdin); 
    // let's get the actual size of the array 
    size_t len = strlen(arr); 
    char is_negative = 0; // 0 means that it is a positive integer, 
    // 1 a negative integer 
    int x = 0; // The integer whose retrieval is our quest 
    if (arr[0] == '-') { 
     is_negative = 1; 
    } else { 
     x = arr[0] - '0'; 
    } 
    // ... We retrieve the other digits in x 
    int i; 
    for (i = 1; i < len-1; ++i) { 
     int digit = arr[i] - '0'; 
     x *= 10; // shift x by a power of ten 
     x += digit; // add the newly retrieved digit. 
    } 
    if (is_negative == 1) { 
     x *= -1; // Let's make x a negative integer 
    } 
    printf("%d\n", x); 
    return 0; // A program that terminates correctly should return 0. 
} 

這個例子假設你的用戶輸入一個有效的數字(可能帶有減號作爲前綴),但沒有什麼能阻止你的用戶進入其它的值,它會產生亂碼輸出。

1

改編爲char類型的數組。首先:arr是一個指針。也許你想使用arr [0]。 如果您正試圖將字符串轉換成一個數字,你必須創建像一個新功能:

int convert(char array[], int lenghtofarray){ 

int N; 
int i; 

for(i=0; i<lenghtofarray; i++){ 
    N+= (array[i]-'0')*exp(10,i); 
} 
return N; 

} 
+0

數組肯定不是一個指針。 – Deduplicator

+0

在c語言中,數組的名稱是指向數組的第一個元素的指針。所以是的,這是一個指針! (事實上​​,如果你只將數組名稱放入一個函數中,那是通過引用而不是按值傳遞的,這意味着它是一個指針! –

+0

不,它在許多上下文中衰減到指針,但它不是,永遠不會成爲指針,這種區別在其他情況下至關重要,所以不要假裝它不存在。 – Deduplicator