将字符转换为整数并打印十进制值

4
char str[20];
printf("Enter anything\n");
scanf("%s",str);
for(int i = 0 ; i<strlen(str) ; i++)
{
   if( isdigit(str[i]))
      printf("%d",(int)str[i]);
}

我尝试了上面的代码,但输出的是数字的ASCII值而不是实际数字。例如,输入:"0",输出:"48"。
当我尝试使用 (int)(str[i]-'0'); 而不是 (int)str[i]); 时,我得到了正确的答案,但我不明白为什么这样是正确的。

最好写成 scanf("%19s",str);,这样更安全。 - chqrlie
今天有趣的事实是,'0' == 48 == 0x30。 - KevinDTimm
@KevinDTimm:仅限ASCII。这个问题中有趣的一点是,C语言规定对于所有数字n0..9范围内,'n' - '0' == n - chqrlie
4个回答

4

您可以通过两种方式修改代码以达到您想要的效果。首先,将printf更改为打印值的字符表示而不是整数表示。

printf("%c", str[i]);

当从键盘输入字符串"0"时,将打印出 "0"。

你在问题中提到的另一个是:

printf("%d", (int)(str[i]-'0'));

你之所以在这里得到正确的答案,是因为计算机存储值的方式。当你输入"0"时,它实际上并不会存储数值0,而是会存储我们称之为"0"的字符的ASCII表示。那个值恰好是整数48。49代表字符"1",以此类推。
为什么呢?想想如何表示字符"M"或者"#"。应该用什么来表示它们? ASCII是已知的256个字符(大约)的表示形式,因为这是我们可以在1字节中存储的总值的数量。因此,"M"是77,"#"是35。
str[i] - '0' 之所以起作用,是因为C/C++处理字符的方式('0'是一个字符)。字符'M'恰好等于值77。因此,以下两行代码等效:
str[i] - '0'

是相同的。
str[i] - 65

因为我输入了代表二进制数66的字符串“1”,我减去了65并得到了值为1的结果。当我要求printf显示我的结果的整数值(%d)时

printf("%d", (int)(str[i] - '0'));

它打印出 "1" 是因为 66 - 65 等于 1。或 '1' - '0' 等于 1。

记住,任何时候当你查看一个字符串或字符时,你并不是在查看值的数字或二进制表示,而是在查看该值的 ASCII 表示。


2
如果已知str[i]是数字,则(int)(str[i]-'0')或更简单的str[i] - '0'是该数字的值,介于09之间。
原因是:C标准规定表示'0''1'、...、'9'的字符必须严格连续。因此,'1'-'0'==1,对所有数字都是如此。

1
@SouravGhosh 当然有。请参阅C11,5.2.1字符集 - P.P
1
@BlueMoon 对的,“上述十进制数字列表中每个字符的值在0之后应比前一个字符的值大1。”我改正了。谢谢。 - Sourav Ghosh

2

仅仅因为这还没有被解决...

不要忘记将字符数组转换为整数或浮点数的其他方式:

char num1[]="1234";
char num2[]="123.5";
int x = atoi(num1);
double y = atof(num2);  
printf("%d\n", x);
printf("%f\n", y);

注意: strtof(,,) 是将字符串转换为浮点数的另一种选择。
strtol(,,) 是将字符串转换为长整型的另一种选择。

1
在你的代码中,
 printf("%d",(int)str[i]);

打印相应的char值(数字)的ASCII值。

另一方面,

printf("%d",(int)(str[i]-'0'));

打印出char的ASCII值和0的ASCII值之间的差异。

如果您查看 ASCII表,从09char表示具有连续的值,因此特定char与ASCII值0的差等于任何特定数字的十进制表示。

顺便说一下,在这种情况下,不需要进行(int)转换,可以直接编写

 printf("%d",str[i]-'0);

获取该 char 数字的十进制值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接