将char数组转换为(负)整数; 因为“array – ‘0’”行而无法编译

所以我有这个代码:

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

当我尝试使用clang的make编译它时,我收到此错误:

 $ 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';并不重要arr[BUFSIZ - 1] = '\0'; 行,这只是不会编译。

我读过int x = arr - '0'; 应该做的伎俩,但它不..

程序的预期用户输入是一个字符串,表示数字,可能带有减号前缀。

我们首先假设用户给出了预期的输入。

此输入存储在大小为SIZE的char数组中:

 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 xa 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字符串也会以空值终止,这意味着字符'\ 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. } 

但是,仍然存在一个错误。 确实,我们的字符串包含一个隐藏的字符,可以计算! 按返回以validation输入时,新行字符'\ 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  #include  #include  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 xa negative integer } printf("%d\n", x); return 0; // A program that terminates correctly should return 0. } 

此示例假定您的用户输入了有效数字(可能带有减号前缀),但NOTHING会阻止您的用户输入其他值,并且会产生乱码输出。

arr是一个CHAR数组。 首先:arr是一个指针。 也许你想使用arr [0]。 如果您尝试将字符串转换为数字,则必须创建一个新函数,如:

 int convert(char array[], int lenghtofarray){ int N; int i; for(i=0; i