【问题标题】:string to integer字符串转整数
【发布时间】:2011-03-14 12:25:23
【问题描述】:

我编写了一个程序,可以将输入到字符串中的数字转换为整数,就像 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();
}

【问题讨论】:

  • 如果您添加了一个示例,说明您期望什么以及您实际遇到的问题,将会很有帮助。
  • 注意:for(A;;B) { if (C) break; ... }可以写成for(A; !C; B) { ... }
  • @Shin 那是我的懒惰先生 :)
  • 比较惯用,打字也少,所以偷懒的解决方案确实是for(A; !C; B)! :D
  • 哈哈,这让我太费神了。我发现添加 break 条件非常有用,就好像我想使用 do while 循环一样,我使用 for 循环并在完成所有操作后使用 break 条件在 for 循环中,所以它总是运行一段时间:p

标签: c


【解决方案1】:

好的。这是对您的代码的快速回顾。嵌入评论。

#include<stdio.h>

#include&lt;stdio.h&gt; 之间留一个空格。

#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];

考虑为您的字符串分配更多空间。十个字相当小。还可以考虑创建一个变量来表示字符串的大小,而不是使用幻数,因为您可能需要在多个位置引用缓冲区大小。

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

没有。不要那样做!!! 函数获取的是一个重大的安全漏洞!。它使您的程序容易受到缓冲区溢出攻击。相反,请使用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 初始化整数,但谷歌搜索我发现当程序运行它时即使在程序终止后也将值存储在静态变量中。这是真的吗?
  • @fahad,一个静态变量,在函数的上下文中,或多或少是一个只在函数范围内可见的全局变量。它不作为局部变量存储在函数的激活记录中,因此与值因调用而异的局部变量不同,静态函数变量在函数的所有调用中保持其状态。也就是说,变量仅在单个进程(程序的单个调用)中持续存在,因此即使在程序终止后它也不会存储其值,但即使在函数终止后它也会存储值。
【解决方案2】:

您的字符串不包含int0, 1, 2, ... 9

它们包含char'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

我会让你自己实现这个简单的算法,因为这是家庭作业。

另见

相关问题

【讨论】:

  • 你对我制作的程序有什么看法?我有一个问题要提出。很多时候我遇到了你通过维基百科给我的标准编码,但我意识到如果你不是那样的话尝试自己的想法不是更好的选择吗?
  • @fahad:Michael Aaron Safyan 对您的代码进行了全面的逐行审查;我真的没有什么新的贡献。我不确定你的第二个问题是关于什么的,但如果是关于学习,那么我相信除了边做边学之外,还应该通过例子来学习。
【解决方案3】:

应该是:

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

【讨论】:

    猜你喜欢
    • 2014-12-16
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多