我编写了一个程序来接收用户输入并将其打印到屏幕上。
示例输入为abc 12 34
。
示例输出是abc 12 34
,但12
和34
应作为整数输入。
使用示例输入,我的程序始终输出为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)) {
.....
}