对于while(~scanf("%[^\n]%*c",a)),连续按两次回车,出现的结果与原因

这是我研究的一个理解性小白问题,我不清楚我的解释准不准确,但是逻辑是没错了,阅读前需要先对~scanf,%[^\n],%*c,缓冲区进行理解。

# include <stdio.h>
void main()
{
    char a[40];
    while(~scanf("%[^\n]%*c",a))
    printf("%s\n",a);
}

运行起来很简单,输入什么字符串,按下回车键后就输出什么字符串,可以达到一个持续输出的效果。在这里插入图片描述感觉没有问题,我就进行了接下来的测试和分析。程序启动,我开始输入nihao,然后按下第一次回车,换行就输出nihao,第一次循环结束。第一次循环中的nihao被%[^\n]读掉了,它无法读换行字符,换行字符被%*c给读掉了。

开始第二次循环,此时缓冲区没有任何未读字符,于是我按下回车键。按照之前的分析,我输入的换行字符会被%*c读掉,输出nihao,接着等待第三次循环的输入,结果却不是。
在这里插入图片描述
结果是无限循环。到底是为什么呢?于是我对%[^\n]中的\n换成其他的字母数字,发现缓冲区中只有以那些其他字母数字开头的字符串,按下回车键,才能出现无限循环。
(%[^\n]读字符串,读到\n就停止,并且不读入\n)
也就是说%[^\n],被停止读入并且又什么也没读到,scanf就会直接返回值0,不再进行%*c的读入。导致了\n一直在缓冲区无法读入。

为了验证,于是我又将%*c提在前面

# include <stdio.h>
void main()
{
    char a[40];
    while(~scanf("%*c%[^\n]",a))
    printf("%s\n",a);
}

在这里插入图片描述

输入nihao ,按下回车,换行输出ihao。显然%*c先读,将n读掉,%[^\n]后读,所以它们读入有先后性。

接下来继续分析,此时进入第二次循环,缓冲区中还有一个换行字符,所以scanf直接继续读,由于%*c放在前面,先进行读入,所以\n就被读掉了。然后缓冲区没有任何未读字符,那么程序便会停在%[^\n]位置等待输入。输入nihao,按下回车后,nihao被复制到a为首地址的内存空间去了,回车字符则还在缓冲区,到第三次循环,回车字符就会被%*c率先读掉。

若在第二次循环时,直接按下回车。第一次循环留下的回车字符被第二次循环的%*c读掉,%[^\n]等待输入,
我按下回车键,此时回车字符输入到缓冲区,%[^\n]遇到回车字符就停止读入,并且回车字符前又没有任何可读字符,结果导致scanf直接返回值0,直接输出ihao。但是到第三次循环,由于%*c的提前,它会先把第二次循环留下在缓冲区中的\n率先读掉,结果是不会出现无限循环。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值