【问题标题】:Sum of n numbersn 个数字的总和
【发布时间】:2015-09-04 10:20:37
【问题描述】:
#include <stdio.h>

int main()
{   
    int m,i,sum,num;

    i=0;
    sum=0;
    scanf("%d ",&m);
    while(i<m){
        scanf("%d ",&num);

        sum=sum + num;

        i=i+1;
        printf("Value of sum= %d\n",sum);
        //continue;
    }
    printf("Sum= %d ",sum);
}

在上面的代码中,它应该显示 n 个数字的总和。但在我的代码中,它采用了一个额外的 m 值(m 是计算总和所需的值的数量)。

例如,如果我将 m 设为 3,则需要 4 个输入并显示 3 的总和。

【问题讨论】:

  • scanf("%d ",&amp;num); --> scanf("%d",&amp;num);
  • 是的,去掉两个scanf中的空格
  • @BLUEPIXY 我认为您应该将此作为答案发布
  • 使用fflushall() 先清除所有输入缓冲区

标签: c


【解决方案1】:

正如其他人(@BLUEPIXY 和 @BillDoomProg)已经在 cmets 中指出的那样,您的问题是您的 scanf 格式字符串中的空格。还要检查this answer

将您的scanf 格式字符串从:

scanf("%d ",&m);
...
scanf("%d ",&num);

收件人:

scanf("%d", &m);
...
scanf("%d", &num);

只要去掉空格就可以了。

scanf()

来自手册

格式字符串由一系列指令(...)组成

指令是以下之一:

一系列空白字符(空格、制表符、换行符等;参见 空间(3))。该指令匹配任意数量的空白,包括 无,在输入中。

另请注意,stdin 已缓冲,因此结果与您的预期略有不同:

man stdin

注意事项

stderr 没有缓冲。流 stdout 在以下情况下被行缓冲 它指向一个终端。直到 fflush(3) 或 调用 exit(3) 或打印换行符。这会产生意想不到的 结果,尤其是调试输出。缓冲模式 可以使用 setbuf(3) 更改标准流(或任何其他流) 或 setvbuf(3) 调用。请注意,如果 stdin 与终端相关联, 终端驱动程序中也可能存在输入缓冲,完全 与 stdio 缓冲无关。 (确实,通常终端输入是线路 缓冲在内核中。)这个内核输入处理可以使用修改 像 tcsetattr(3) 这样的调用;另请参见 stty(1) 和 termios(3)。

那么,让我们逐步检查您的程序。

您的程序开始运行并输入数字 2。输入缓冲区如下所示:

2\n

scanf("%d ", &amp;m) 将 2 分配给 m 变量并开始尝试匹配空格。它得到一个NLEOL。控制权仍然在这个 scanf 上,因为它只是匹配了一个换行符(被认为是一个空格)并且正在等待匹配更多,但是它得到了 End-Of-Line,所以当你输入它时它仍然在等待:

1\n

然后再次读取stdin,意识到输入流中的下一个字符不是空格并返回(它的格式字符串条件已完成)。此时,您进入循环并调用下一个scanf("%d ",&amp;num),它想要读取一个整数,它确实这样做了:它读取 1 并将其存储在num 变量。然后它再次开始匹配空格并获取换行符并重复上述模式。那么当你输入时:

2\n

第二个scanf 得到一个不同于空格的字符 并返回,因此您的循环范围会继续执行打印当前的sum。 不满足循环中断条件,因此重新开始。它调用 scanf 它有效地将一个整数读入变量,然后 模式不断重复......

3\n

它正在等待一个空格,但它得到了一个字符。所以你的 scanf 返回现在满足循环中断条件。这是您退出循环的地方,打印整个sum 并得到奇怪的感觉 “添加” 3 个数字,但总和仅添加前 2 个(如您所愿 首先)。

您可以通过简单地添加代码来检查 3 是否挂在 stdin 中:

#include <stdio.h> 

int main()
{

    int m, i, sum, num;
    char c;

    i = 0;
    sum = 0;
    scanf("%d ", &m);

    while (i < m) {
        scanf("%d ", &num);

        sum = sum + num;

        i = i + 1;
        printf("Value of sum= %d\n", sum);
    }

    while((c = getchar()) != '\n') 
        printf("Still in buffer: %c", c);

    return 0;
}

这将输出(当然是上面的输入):

$ ./sum1
2
1
2
Value of sum= 1
3
Value of sum= 3
Still in buffer: 3

【讨论】:

  • 你的回答很有用。我想问你关于 C 的深度学习。我刚开始学习 C,我想进入深度学习的心情。我该怎么做?我正在借助视频教程。
  • 从头开始学习每一件事。试图了解有关 C 的一切。
  • @AryanRagavan 阅读K&R Book,然后跳转到this site。 C 语言的特点是它是一种相当简单 的语言,并且不应该花很长时间来了解它的工作原理。但是 C 是为构建操作系统而设计的:这意味着您应该了解计算机的工作原理,以便充分发挥其功能。一个很好的起点是优秀的书 (WARNING PDF) Programming from the Ground Up,它也会教你一些汇编。
  • @AryanRagavan 至于视频教程,我帮不了你。我从来没有看过任何介绍性的 C 视频讲座,所以我不能指出一个好的。不过,在一些好东西上,Rusty RusselYouTube 上有一些非常不错的视频。
【解决方案2】:

这是因为scanf 行中的%d 后面有一个空格。

改变

scanf("%d ",&num);

收件人

scanf("%d",&num);   

Scanf 通常会忽略空格,因此您不希望格式字符串中有空格。

【讨论】:

    【解决方案3】:

    这是extra space in scanf() 的原因。换scanf("%d ",&amp;num) to scanf("%d",&amp;num)

    来自Scanf(), fscanf(),你可以关注这个。

    scanf() 系列函数从控制台或从 FILE 流,对其进行解析,并将结果存储在您的变量中 在参数列表中提供。

    格式字符串与 printf() 中的格式字符串非常相似,您可以 告诉它读取一个“%d”,例如一个 int。但它也有 附加功能,最值得注意的是它可以吃掉其他 您在格式字符串中指定的输入中的字符。

    你应该写:

    int main()
    {
        int m,i,sum,num;
    
        i=0;
        sum=0;
        scanf("%d",&m);
        while(i<m){
            scanf("%d",&num);
    
            sum=sum + num;
    
            i=i+1;
            printf("Value of sum= %d\n",sum);
            //continue;
        }
        printf("Sum= %d ",sum);
    }
    

    【讨论】:

      【解决方案4】:

      重构后的代码如下所示

      #include <stdio.h>
      
      int main() {
          int m, num, sum = 0;
          scanf("%d", &m);    // Let scanf automatically skip whitespace
          while (m--) {
              scanf("%d", &num);
              sum += num;
          }
          printf("Sum= %d\n", sum);
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-03
        • 2011-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多