c语言 while (getchar() != '\n')为什么可以过跳过回车?

请问这段代码为什么可以跳过回车?这写不是跳过不是回车的字符吗?谢谢

(1)分清键盘缓冲区 和 输入流数据缓冲区。
当我们在键盘上按键时,按入的 一个个 键值都 在 键盘缓冲区 里,只有当 新行键 到来时,
按入的 这些 键值(字符们,和新行键) 才从 键盘缓冲区 送入 输入流数据缓冲区。
(2)getchar() 是到输入流数据缓冲区去读取一个字符,
当 输入流数据缓冲区 没有数据时,读语句 就等待,
当 输入流数据缓冲区 有 数据 是,就读 最先 进来的那个字符,读一个,就从输入流数据缓冲区里清除掉这个字符。
getchar() != '\n' 是 进一步 判断 刚 读入的这个字符 是不是新行键。
(3)while (getchar() != '\n' ) continue;
与 while (getchar() != '\n' ) 空语句 ; 作用 相同,就是 到 输入流数据缓冲区去读取一个一个字符,只要读到的 不是 '\n', 就继续读 (读一个清除一个),直到 读到 '\n'。其作用等于 “清除 输入流数据缓冲区”。
(4) 输入流数据缓冲区 被 清除后,程序 回到
while (getchar() != 'y' ){ 循环体 };
这时,输入流数据缓冲区 没东西。等待 键盘缓冲区 把东西 送过来。
键盘缓冲区 等待 用户 拍入 字符,并等待 '\n' 到来,
一旦 '\n' 到来, 键盘缓冲区 里的内容 才送到 输入流数据缓冲区。
输入流里若有 'y', 就 结束 这个 while 循环。
否则 while (getchar() != '\n' ) 就会 “清除 输入流数据缓冲区”,回到等待 'y' 的 循环。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2017-01-10
这段代码是跳过所有输入的字符,直到遇到\n
就跳出内层循环,去进行是否y的判断

因为getchar是以回车结束输入
所以它判断完是否是y之后 需要过滤掉后面所有的字符,包括\n
再开始录入判断追问

明白能过滤首字符后的所有字符,但还是不解,为何能过滤掉\n
比如输入了abcd然后按下回车,刷新缓冲区,此时判断a!=y,然后打印请按y。然后进入第2个while,只要不是\n,就跳过。此时过滤掉了bcd。然后发现是\n了,为什么不能再回到第一个while中再打印请按y呢?
\n到底是在什么位置过滤掉的?

追答

"然后进入第2个while,只要不是\n,就跳过"

事实上 这个时候 就算是\n 这个字符是不是也被getchar取出来了?
因为判断是否为\n的前提就是要把输入缓冲区内的\n取出来

跳出第二个循环,\n就已经被过滤了

追问

你的意思这个\n实际是被消耗掉了?
那如果把while (getchar() != '\n')改成while (getchar() != 's')
为什么输入ss的时候会打印2遍 请按y?
按说判断第1个s不是y,并打印。第2个s被消耗掉,最后一个\n被跳过啊

追答

你要知道 getchar 你自己输入的内容 是用回车结束的

所以实际键盘缓冲区最后会多一个\n
你输入ss 实际缓冲区里是三个字符 s s 和\n
第一个字符用于判断 于是失败了 打印出 请按y
第二个字符被用于内层循环的判断 ,由于判断成功,第二层循环跳出,但是这个s仍然被消耗掉
第三个字符\n用于是否是y的判断 ,失败 所以又打引出 请按y

我们再看原来那个题 你输入s回车
第一个s用于判断 ,失败并打印请按y
第二个回车就被内层循环消耗掉,再次回到外层循环并等待输入

追问

你说的这3步过程不对,通过vs的逐语句观察发现
输入ss按下回车后,判断第1个s不是y,打印 请按y
进入第2个while,判断不是s跳过,并且回到第1个循环中,再判断第2个s不是y,又打印一次,所以打印了2个
然后进入第2个while,并不判断\n,而是要求输入
此时输入d并按下回车,进行跳过,然后跳过\n(d后面的\n)。
并且不会回到第一个while中,而是一直循环在第2个while。
我便更无法理解

追答

我说得没错

你把程序改下就知道了

#include<stdio.h>
int main(void)
{
char c;
    while(c=getchar(),c!='y')
    {
    printf("要按y\n");
    while(c=getchar(),c!='s')
  continue;
    }
    return 0;
}

追问

上面是我理解错了。我说\n为什么无故消失了,实际上s是被消耗了,第二打印是\n输出的
我再整理下思路,没问题就采纳了,关于这个要是不懂,再问啊,先谢了

本回答被提问者采纳
相似回答