字符串转整数

3

我做了一个程序,将输入的数字字符串转换为整数,类似于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();
}

如果您在问题中添加一个期望输出和实际输出的示例,将会非常有帮助。 - ChrisF
3
请注意:for(A;;B) { if (C) break; ... } 可以写成 for(A; !C; B) { ... } - ShinTakezou
@Shin 那是我的懒惰,先生 :) - user379888
它更符合惯用语,并且需要输入的内容更少,因此懒人的解决方案确实是 for(A; !C; B)! :D - ShinTakezou
哈哈,这让我花费了太多的精力。我发现事后添加退出条件非常有帮助,因为如果我想使用do-while循环,我会使用for循环,并在完成所有操作后使用退出条件,这样它就总是运行一段时间 :p - user379888
3个回答

5
您的字符串中不包含整数值0, 1, 2, ... 9。它们包含字符值'0', '1', '2', ... '9'。例如在ASCII中编码,'0' == 48
您需要将char转换为int;一种方法是通过减去'0'来实现,例如:
z = (string[x-i+1] - '0') * y;

相关问题


关于霍纳方案

您也可以通过不使用pow,而使用Horner方案来做得更好。

以下是一个示例(此处的^表示指数,而不是按位异或):

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

一开始可能看起来有点复杂,但实际上并不是。你只需要从左到右逐个读取数字,并在加上下一位数字前将得到的结果乘以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

由于这是作业,我将让您自己实现这个简单的算法。

另请参阅

相关问题


关于我写的程序,你有什么看法?我有一个问题要提出。很多时候,我会遇到像你通过维基百科给我的标准编码,但我意识到,如果你自己尝试一下这个想法,那不是更好的选择吗? - user379888
@fahad:Michael Aaron Safyan 对你的代码进行了全面的逐行审查;我没有什么新的贡献。我不确定你的第二个问题是关于什么的,但如果是关于学习的话,我相信除了通过实践学习外,还应该通过例子学习。 - polygenelubricants

5

好的。以下是您代码的快速审查。已嵌入注释。

#include<stdio.h>

#include<stdio.h> 之间留一个空格。

#include<conio.h>

这是一个非标准的仅适用于 Windows 的头文件,您不需要它。请勿包含此文件。

#include<math.h>
#include<string.h>

在包含标题时再次使用空格。

void main(void)

虽然这是合法的,但更常见的是在主函数中找到签名int main(int argc, char* argv[])。我建议您使用该签名。

 {
     static int sum;

为什么要把它设为静态的?你是计划重复调用main并使sum的先前结果从一次main调用持续到另一次吗?如果不是,那就不要将其设为静态。

 int i,x,y,z;
 char string[10];

考虑为字符串分配更多的空间。10个字符太少了。还要考虑创建一个变量来表示字符串的大小,而不是使用一个神奇数字,因为你可能需要在多个地方引用缓冲区的大小。

printf("Enter a string:\n");
gets(string);

不要这样做!!!函数gets是一个重大的安全漏洞!它会使你的程序容易受到缓冲区溢出攻击。相反,使用fgets,并指定你想要填充的缓冲区的大小,以避免溢出。你永远不应该使用纯粹的gets。

x=strlen(string);

考虑为x选择一个更具描述性的名称。也许可以选择len。创建变量时,标识符长度超过一个字母是完全可以的(而且是好的)。

for(i=0; ;i++)
{
  if(string[i]=='\0')
  {
     break;
  }

考虑将终止条件放在for循环中:for(i = 0; string[i]!='\0'; i++)

  y=pow(10,i);
  z=string[x-i+1]*y;

提示:有一种比使用pow更明智的方法来完成这个任务。

  sum+=z;
 }
 printf("%d",sum);

好的。上面的内容没问题,不过你可能想使用"%d\n"。

 getch();

你不应该在所有系统上都这样做。相反,应该这样做:

#ifdef _WIN32
    system("pause");
#endif

如果可能的话,我建议您避免那种奇怪的暂停行为。假设您的教授使用自动化脚本来验证程序的输出。在程序中加入任何形式的暂停(即使在Windows上),都会破坏这样的脚本。如果您不想在Windows上看到终端窗口消失,您应该从命令提示符中调用您的程序。
}

如果你按照我建议的更改签名为返回int类型,那么你需要在函数末尾添加语句return 0;


关于静态整数的问题,我想问一下,据我所知,它们只用于将整数初始化为0,但是通过谷歌搜索,我发现当程序运行时,它会将值存储在静态变量中,即使程序终止了也是如此。这是真的吗? - user379888
@fahad,在函数的上下文中,静态变量更或多或少是一个全局变量,只在函数的范围内可见。它不像本地变量那样存储在函数的激活记录中作为本地变量,因此,与值从调用到调用变化的本地变量不同,静态函数变量在所有调用函数的情况下都保持其状态。也就是说,变量仅在单个进程(程序的单个调用)中持续存在,因此它不会在程序终止后存储其值,但它确实在函数终止后存储值。 - Michael Aaron Safyan

2

应该是:

z=(string[x-(i+1)]-'0')*y;

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