You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于getc()与getchar()调用的输出异常问题咨询

问题拆解与解决方案

先把你的代码贴出来方便对照:

printf("%c %c", getc(stdin), getc(stdin)); 
rewind(stdin); 
printf("\n"); 
printf("%c %c", getchar(), getchar()); 

你预期输入s+回车、s+回车后得到s s s s,但实际出现了顺序反转和奇怪的空格/换行,下面逐个解答你的疑问:

Q1:按下s、回车后输出顺序为啥反转了?

这是踩到了C语言未定义行为的坑!C标准并没有规定函数参数的求值顺序——也就是说,printf("%c %c", getc(stdin), getc(stdin))里的两个getc(stdin),编译器想先调用哪个就调用哪个。而VS2017的编译器是从右往左求值的:

当你输入s+回车(对应字符s和\n),右边的getc先读取到\n,左边的getc再读取到s,所以printf会输出\n s——也就是先换行,再输出s,看起来就和你输入的顺序完全反过来了。

Q2:第三行和第六行为啥出现类似s 的奇怪格式?

这里有两个核心问题:

  1. rewind(stdin)在Windows控制台完全没用:rewind是给文件流设计的,能把文件指针移回开头,但Windows控制台的输入是行缓冲的交互式流,不是可回溯的文件,所以rewind根本没法把已经读取的字符“放回去”。
  2. 输入回显+行缓冲的叠加效果:Windows控制台默认会实时回显你按下的每个字符(比如你按s就显示s,按回车就换行),再加上程序的输出,两者混在一起就显得混乱。另外,你输入的每个s后面都跟着回车\n,当getc/getchar读到\n时,printf输出它就会换行,再加上%c %c里的空格,就出现了你看到的“换行后跟着s+空格”的奇怪格式。

另外,第二次的printf("%c %c", getchar(), getchar())同样面临参数求值顺序的问题,还是从右往左读,导致读取\n和s,输出\n s,进一步加剧了格式混乱。

怎么改成你想要的效果?

要避开未定义行为和控制台的坑,你得先把字符读出来存好,再输出,同时处理输入缓冲。如果你想输入两次s+回车后得到s s s s,可以这样写:

// 读取第一个s,跳过后续的回车
char c1 = getc(stdin);
getc(stdin); // 吃掉回车
// 读取第二个s,跳过后续的回车
char c2 = getc(stdin);
getc(stdin); // 吃掉回车
// 按预期输出
printf("%c %c %c %c\n", c1, c1, c2, c2);

如果想保留分步输出的逻辑,也要先把字符读取到变量里,避免参数求值顺序的问题:

// 先读取字符到变量,保证顺序正确
char c1 = getc(stdin);
char c2 = getc(stdin);
printf("%c %c\n", c1, c2);

// 清空当前行剩余的输入缓冲
while (getchar() != '\n');

// 读取第二组字符
char c3 = getchar();
char c4 = getchar();
printf("%c %c\n", c3, c4);

内容的提问来源于stack exchange,提问作者lev.1 code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 17:12:47