将字符类型 '0'-'9' 转换为 int 类型,并打印为 C 语言的标准输出



我编写了一个程序来接收用户输入并将其打印到屏幕上。

示例输入为abc 12 34

示例输出是abc 12 34,但1234应作为整数输入。

使用示例输入,我的程序始终输出为abc 122 344.我已经为此工作了很长时间,但我仍然无法弄清楚。可以帮我检查我的代码吗?谢谢。

我的 gcc 版本是 4.1.2 .

#include<stdio.h>
#include<stdlib.h>
int main()
{
char c;
char *str = NULL;
str = (char *)malloc(20*sizeof(char)); /*just sample code, not robust*/
memset(str,'',20*sizeof(char)); 
if(str == NULL)
{
fprintf(stderr,"Error: failed to allocate memory.n"); fflush(stderr);
return 0;
}
/*store user input*/
int index = 0;
while((c=getchar()) != 'n')
{
*(str+index) = c;
index++;
}
int digit = 0;
for(index = 0; *(str+index)>0; index++)
{
if((*(str+index)>='a') &&( *(str+index)<='z'))
{
fprintf(stdout,"%c",*(str+index)); fflush(stdout);
}
else if((*(str+index)>='0') &&( *(str+index)<='9'))
{
/*handling the case that a number with more than one digit*/
if(*(str+index+1)>='0' && *(str+index+1)<='9')
{
digit=10*(digit+atoi(str+index));
}
else
{
digit += atoi(str+index);   
fprintf(stdout,"%d",digit); fflush(stdout);
digit = 0;
}           
}
else
{   
fprintf(stdout,"%c",*(str+index)); fflush(stdout);
}
}
printf("n");
free(str);
return 0;
}

你不应该使用atoi:它将字符串转换为int,而不是单个char

事情是这样的:当你看到一个两位数时,比如说,34,第一次迭代将两个数字都atoi,得到34,然后乘以十,得到340。接下来的迭代拾取4,并愉快地将其添加到340,以获得344的累积结果。

如果要将表示数字的单个char转换为int,请使用减法:

digit = *str - '0';

此外,您处理多位数的代码是非正统的,因此难以理解。当您看到下一个字符是数字时,不应将当前值乘以 10,而应在看到数字时将前一个值乘以 10。这甚至适用于第一个数字,当前一个值为0时,因为十乘以零仍然是零。

应消除if(((*str+index+1)>='0') && (*str+index+1)<='9')及其then分支,并按如下方式修改其else分支:

digit = 10*digit + *(str+index) - '0';
if (((*str+index+1)<'0') || (*str+index+1)>'9') {
fprintf(stdout,"%d",digit); fflush(stdout);
digit = 0;
}

两个快速更改。

首先,如前所述,atoi()获取一个字符串并返回一个 int。由于您只执行 1 个字符 (0-9),因此只需从字符"0"中减去它即可。

digit=10*(digit+(*(str+index)-'0')); //instead of atoi(str+index)

为什么要减去"0"?它归结为数字的 ASCII 值。

字符 '0' 的值为 30 10,"1" 的值为 3110,因此:

int a = '0' - '0'; // that's  30-30, or 0 as an int
int b = '1' - '0'; // that's  31-30, or 1 as an int

如果您在当前使用的两个位置进行此调整atoi()

...
digit=10*(digit+atoi(str+index));
}
else
{
digit += atoi(str+index); 
...

更改为:

...
digit=10*(digit+(*(str+index)-'0'));
}
else
{
digit += *(str+index)-'0';   
...

您的代码现在将按照您希望的方式工作。还有一点,您有一个if/if else/else检查 a-z、0-9,然后是其他任何东西。

因为你的第一if和你的else是相同的代码,这意味着可以在那里进行简化。只需删除整个第一个if并将else if更改为仅if,即可获得与您正在做的事情完全相同的事情。

只用sscanf怎么样? 像这样:

sscanf(str, "%s %d %d", str1, &num1, &num2);

如果您不能使用sscanf,出于某种原因,那么您至少应该使用isalpha()isdigit()分别检查字符和数字。

所以不要使用它:

if((*(str+index)>='a') &&( *(str+index)<='z')) {
.....
}

使用这个:

if (isalpha(*str+index)) {
.....
}

最新更新