所以我有这段代码:
#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);
}
当我尝试编译它时,使用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';
行并不重要,这就不会编译。
我已经读过int x = arr - '0';
应该做的伎俩,但它没有..
答案 0 :(得分:1)
arr是一个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;
}
答案 1 :(得分:1)
程序的预期用户输入是一串字符,表示数字,可能带有减号前缀。
我们首先假设用户给出了预期的输入。
此输入存储在大小为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 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字符串也会以空值终止,这意味着字符“\ 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.
}
此示例假定您的用户输入了有效数字(可能带有减号前缀),但NOTHING会阻止您的用户输入其他值,并且会产生乱码输出。