正如其他人(@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 ", &m) 将 2 分配给 m 变量并开始尝试匹配空格。它得到一个NL 和EOL。控制权仍然在这个 scanf 上,因为它只是匹配了一个换行符(被认为是一个空格)并且正在等待匹配更多,但是它得到了 End-Of-Line,所以当你输入它时它仍然在等待:
1\n
然后再次读取stdin,意识到输入流中的下一个字符不是空格并返回(它的格式字符串条件已完成)。此时,您进入循环并调用下一个scanf("%d ",&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