我已经制作了一个程序,将输入到字符串中的数字转换为像do一样的整数atoi,但它给出了错误的输出.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>
void main(void)
{
static int sum;
int i,x,y,z;
char string[10];
printf("Enter a string:\n");
gets(string);
x=strlen(string);
for(i=0; ;i++)
{
if(string[i]=='\0')
{
break;
}
y=pow(10,i);
z=string[x-i+1]*y;
sum+=z;
}
printf("%d",sum);
getch();
}
Run Code Online (Sandbox Code Playgroud)
您的字符串不包含int值0, 1, 2, ... 9.
它们包含char值'0', '1', '2', ... '9'.以ASCII编码,'0' == 48.
你需要转换char为int; 一种方法是减去'0',例如:
z = (string[x-i+1] - '0') * y;
Run Code Online (Sandbox Code Playgroud)
'0'和48!你也可以pow通过使用Horner方案不使用它做得更好.
这是一个例子(这里^表示取幂而不是bitwise-xor):
8675309 = 8*10^6 + 6*10^5 + 7*10^4 + 5*10^3 + 3*10^2 + 0*10^1 + 9*10^0
= (((((8*10 + 6)*10 + 7)*10 + 5)*10 + 3)*10 + 0)*10 + 9
Run Code Online (Sandbox Code Playgroud)
一开始可能看起来很复杂,但事实并非如此.您基本上从左到右读取数字,并在添加下一个数字之前将结果乘以10.
以表格形式:
step result digit result*10+digit
1 init=0 8 8
2 8 6 86
3 86 7 867
4 867 5 8675
5 8675 3 86753
6 86753 0 867530
7 867530 9 8675309=final
Run Code Online (Sandbox Code Playgroud)
我会让你自己实现这个简单的算法,因为这是功课.
好.以下是对代码的快速回顾.嵌入评论.
#include<stdio.h>
Run Code Online (Sandbox Code Playgroud)
在#include和之间留一个空格<stdio.h>.
#include<conio.h>
Run Code Online (Sandbox Code Playgroud)
这是您不需要的非标准Windows专用标头.不要包括这个.
#include<math.h>
#include<string.h>
Run Code Online (Sandbox Code Playgroud)
在包含标题时再次使用空格.
void main(void)
Run Code Online (Sandbox Code Playgroud)
虽然这是合法的,但更常见的是将签名int main(int argc, char* argv[])作为主要功能的签名.我建议你使用那个签名.
{
static int sum;
Run Code Online (Sandbox Code Playgroud)
你为什么要这个静态?您是否计划反复调用main并将之前的结果sum从main调用到另一个?如果没有,那么不要让它静止.
int i,x,y,z;
char string[10];
Run Code Online (Sandbox Code Playgroud)
考虑为字符串分配更多空间.十个字符很小.还要考虑创建一个变量来表示字符串的大小,而不是使用幻数,因为您可能需要在多个位置引用缓冲区大小.
printf("Enter a string:\n");
gets(string);
Run Code Online (Sandbox Code Playgroud)
不,不要那样做!函数获取是一个主要的安全漏洞!.它使您的程序容易受到缓冲区溢出攻击.而是使用fgets,并指定要填充的缓冲区的大小,以便它不会溢出缓冲区.你永远不应该使用普通的获取.
x=strlen(string);
Run Code Online (Sandbox Code Playgroud)
考虑为x选择更具描述性的名称.也许吧len.创建标识符长于单个字母的变量是完全正确的(也是好的).
for(i=0; ;i++)
{
if(string[i]=='\0')
{
break;
}
Run Code Online (Sandbox Code Playgroud)
考虑将终止条件放在for循环中; for(i = 0; string[i]!='\0'; i++).
y=pow(10,i);
z=string[x-i+1]*y;
Run Code Online (Sandbox Code Playgroud)
提示:有一种比使用pow更聪明的方法.
sum+=z;
}
printf("%d",sum);
Run Code Online (Sandbox Code Playgroud)
好.以上情况很好,但您可能想使用"%d \n".
getch();
Run Code Online (Sandbox Code Playgroud)
你真的不应该在所有系统上这样做.相反,做:
#ifdef _WIN32
system("pause");
#endif
Run Code Online (Sandbox Code Playgroud)
但是,如果可能的话,我会建议你避免那种奇怪的暂停行为.假设您的教授使用自动脚本来验证程序的输出.在程序中放置任何类型的暂停(即使在Windows上)都会破坏这样的脚本.如果您不希望终端窗口在Windows上消失,则应从命令提示符调用程序.
}
Run Code Online (Sandbox Code Playgroud)
如果您要按照我的建议将签名更改为返回int的内容,那么您可能希望return 0;在函数结束之前添加该语句.