您的方案的預期用戶輸入是代表數字字符的字符串,可能與一個減號作爲前綴。
假設在第一個用戶給出了一個預期的輸入。
該輸入被存儲在大小尺寸的字符數組:
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.
}
這個例子假設你的用戶輸入一個有效的數字(可能帶有減號作爲前綴),但沒有什麼能阻止你的用戶進入其它的值,它會產生亂碼輸出。
'arr [0] - '0''? – timrau
目前還不清楚,你正在嘗試做什麼。 int x =(int)arr - '0'不應該產生任何錯誤,但我很難確定這是否是預期的行爲。 arr [0] - '0'會給你輸入的第一個數字。 – dureuill
謝謝,現在的作品,但不lil'bit理所應當: 'jharvard @電器(〜/ CS50/PSET1):./test 輸入:-123 輸出:-3' 'jharvard @家電(〜/ CS50/pset1):./test 輸入:123 輸出:1' 爲什麼在負數的情況下?它應該返回第一位,而不是最後一位。 – spaffy