聊聊C语言中scanf()怎么解决输入缓冲区残留‘/n’的问题

袁保康 2013-05-26 06:26:16
聊聊C语言中scanf()怎么解决输入缓冲区残留‘/n’的问题
因为 scanf %c 只是读入一个字符,而你在输入时实际上输入的是:某个字符
+Enter,Enter 产生的\n 也会停留在输入缓冲区中,下次调用 scanf %c 时就会直接读到
它而不是等待你再次输入!

#include <stdio.h>

int main(void)
{
int n = 0;
char ch = 0;

printf("Input n: ");
scanf("%d", &n);

printf("Input A - D: ");
//scanf("%c", &ch); //方法1:消除上一个'/n' 有效
//fflush(stdin); //方法2:消除上一个'/n' 无效
//scanf(" %c", &ch); //方法3:(前边添加一个空格)消除上一个'/n' 有效
scanf("%c", &ch); //大家都用什么方法,为什么fflush不可以呢?
printf("\n");
if (ch == 'A')
{
}
else
{
}
printf("This Program is end!\n");
return 0;
}

...全文
3611 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
assetmm 2015-11-20
  • 打赏
  • 举报
回复 1
while((getchar()!='\n')) continue;
l630702030 2015-10-14
  • 打赏
  • 举报
回复
不好意思,你的方法一没看明白,,,能解释一下吗
SKATE11 2013-05-27
  • 打赏
  • 举报
回复
楼主 是"\n"不是"/n" ............
赵4老师 2013-05-27
  • 打赏
  • 举报
回复
每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值
赵4老师 2013-05-27
  • 打赏
  • 举报
回复
个人意见:最好的策略就是在scanf里面永远不用%c!
赵4老师 2013-05-27
  • 打赏
  • 举报
回复
引用 14 楼 kangear 的回复:
[quote=引用 12 楼 zhao4zhong1 的回复:] 在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。
#include <stdio.h>
char s[]="123 ab 4";
char *p;
int v,n,k;
void main() {
    p=s;
    while (1) {
        k=sscanf(p,"%d%n",&v,&n);
        printf("k,v,n=%d,%d,%d\n",k,v,n);
        if (1==k) {
            p+=n;
        } else if (0==k) {
            printf("skip char[%c]\n",p[0]);
            p++;
        } else {//EOF==k
            break;
        }
    }
    printf("End.\n");
}
//k,v,n=1,123,3
//k,v,n=0,123,3
//skip char[ ]
//k,v,n=0,123,3
//skip char[a]
//k,v,n=0,123,3
//skip char[b]
//k,v,n=1,4,2
//k,v,n=-1,4,2
//End.
亲爱的赵老师: 很难过的告诉你,fflush(stdout)rewind(stdin),似乎在下边的程序中显得毫无作用。我一直在用GDB调试:
#include <stdio.h>

int main(void)
{
	int n = 0;
	char ch = 0;

	printf("Input n: ");
	scanf("%d", &n);

	printf("Input A - D: ");
	fflush(stdout);
	rewind(stdin);
	scanf("%c", &ch);
	printf("\n");
	printf("This Program is end!\n");
	return 0;
}
关于检测返回值,听起来可行,但是觉得我就一个scanf,就得着大动干戈吗?显得有点麻烦了。您说呢?[/quote] 我很高兴地告诉你,你理解错误: 在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。
袁保康 2013-05-27
  • 打赏
  • 举报
回复
引用 26 楼 xiayiguo 的回复:
[quote=引用 24 楼 kangear 的回复:] [quote=引用 21 楼 xiayiguo 的回复:] [quote=引用 20 楼 kangear 的回复:] [quote=引用 18 楼 xiayiguo 的回复:] 可是不明白为什么 fflush(stdin)不行? 请指教!
有图有真像! [/quote] 好吧! 这是什么软件啊?[/quote] 上边用的eclipse cdt!如果不能说明问题,那么下边这个呢? [/quote] 这些都是linux里面的软件吗? 那个画箭头的又是什么软件啊?呵呵。。 我明白你的意思, 这些软件都好高端啊!对于刚入门不久的新人来说![/quote] 软件都好高端??? eclipse cdt 类似win下的vc 第二个是终端而已,类似cmd。 图上的画箭头的就是一个截图软件,截图之后再画箭头,功能类似win下的画图板。
袁保康 2013-05-27
  • 打赏
  • 举报
回复
引用 23 楼 lin5161678 的回复:
[quote=引用 1 楼 kangear的发帖:]
因为 scanf %c 只是读入一个字符

实际上 scanf %c 是用于读取多个字符 只是默认读取1个字符
比如
#include <stdio.h>

int main()
{
char ch[12];
scanf("%5c", ch);
for(int i=0; i<5; ++i)
printf("%c", ch[i]);
return 0;
}
[/quote]

如果有了上下文,结果永远都是那么的意外:

ch[0]='/n'是不是很意外!
xiayiguo 2013-05-27
  • 打赏
  • 举报
回复
引用 24 楼 kangear 的回复:
[quote=引用 21 楼 xiayiguo 的回复:]
[quote=引用 20 楼 kangear 的回复:]
[quote=引用 18 楼 xiayiguo 的回复:]
可是不明白为什么 fflush(stdin)不行? 请指教!

有图有真像!
[/quote]
好吧! 这是什么软件啊?[/quote]
上边用的eclipse cdt!如果不能说明问题,那么下边这个呢?
[/quote]
这些都是linux里面的软件吗? 那个画箭头的又是什么软件啊?呵呵。。 我明白你的意思, 这些软件都好高端啊!对于刚入门不久的新人来说!
xiayiguo 2013-05-27
  • 打赏
  • 举报
回复
引用 22 楼 lin5161678 的回复:
引用 18 楼 xiayiguo 的回复:
可是不明白为什么 fflush(stdin)不行? 请指教!
fflush 用于 stdin 的行为是不确定的 我记得是实现吧 简单的说 不可靠的做法
我记得在论坛里,有一篇帖子就是关于这个的, 好像说fflush(stdin)可以清楚缓存区,
袁保康 2013-05-27
  • 打赏
  • 举报
回复
引用 21 楼 xiayiguo 的回复:
[quote=引用 20 楼 kangear 的回复:]
[quote=引用 18 楼 xiayiguo 的回复:]
可是不明白为什么 fflush(stdin)不行? 请指教!

有图有真像!
[/quote]
好吧! 这是什么软件啊?[/quote]
上边用的eclipse cdt!如果不能说明问题,那么下边这个呢?
lin5161678 2013-05-27
  • 打赏
  • 举报
回复
引用 1 楼 kangear的发帖:
因为 scanf %c 只是读入一个字符
实际上 scanf %c 是用于读取多个字符 只是默认读取1个字符 比如
#include <stdio.h>

int main()
{
	char ch[12];
	scanf("%5c", ch);
	for(int i=0; i<5; ++i)
		printf("%c", ch[i]);
	return 0;
}
lin5161678 2013-05-27
  • 打赏
  • 举报
回复
引用 18 楼 xiayiguo 的回复:
可是不明白为什么 fflush(stdin)不行? 请指教!
fflush 用于 stdin 的行为是不确定的 我记得是实现吧 简单的说 不可靠的做法
xiayiguo 2013-05-27
  • 打赏
  • 举报
回复
引用 20 楼 kangear 的回复:
[quote=引用 18 楼 xiayiguo 的回复:]
可是不明白为什么 fflush(stdin)不行? 请指教!

有图有真像!
[/quote]
好吧! 这是什么软件啊?
袁保康 2013-05-27
  • 打赏
  • 举报
回复
引用 18 楼 xiayiguo 的回复:
可是不明白为什么 fflush(stdin)不行? 请指教!

有图有真像!
袁保康 2013-05-27
  • 打赏
  • 举报
回复
引用 10 楼 ForestDB 的回复:
深入理解“流”这个概念。 理解后就知道可以“吸收”\n,可以忽略。
可能真是不理解,遇到一个小问题,引出一个大问题,编程无小事呀。
xiayiguo 2013-05-27
  • 打赏
  • 举报
回复
可是不明白为什么 fflush(stdin)不行? 请指教!
袁保康 2013-05-27
  • 打赏
  • 举报
回复
引用 13 楼 zhao4zhong1 的回复:
#include <stdio.h>
char s[]="123 ab\t4\n5\n6";
char *p;
char c;
int n,k;
char *ch(char cc) {
    static char s[3];

    if ('\t'==cc)
        sprintf(s,"\\t");
    else if ('\n'==cc)
        sprintf(s,"\\n");
    else
        sprintf(s,"%c",cc);
    return s;
}
void main() {
    p=s;
    while (1) {
        k=sscanf(p,"%c%n",&c,&n);
        printf("k,c,n=%d,%s,%d\n",k,ch(c),n);
        if (1==k) {
            p+=n;
        } else if (0==k) {
            printf("skip char[%s]\n",ch(p[0]));
            p++;
        } else {//EOF==k
            break;
        }
    }
    printf("End.\n");
}
//k,c,n=1,1,1
//k,c,n=1,2,1
//k,c,n=1,3,1
//k,c,n=1, ,1
//k,c,n=1,a,1
//k,c,n=1,b,1
//k,c,n=1,\t,1
//k,c,n=1,4,1
//k,c,n=1,\n,1
//k,c,n=1,5,1
//k,c,n=1,\n,1
//k,c,n=1,6,1
//k,c,n=-1,6,1
//End.
忘了刷新了,后看到了第二个回帖。我似乎冷静下来,好好研究您这个程序证明了什么。然后再说结果了。先GDB调试 它个几十遍。
xiayiguo 2013-05-27
  • 打赏
  • 举报
回复
while (getchar () != '\n')
continue;

经常用这个
袁保康 2013-05-27
  • 打赏
  • 举报
回复
引用 11 楼 evencoming 的回复:
[quote=引用 8 楼 kangear 的回复:] [quote=引用 4 楼 evencoming 的回复:] scanf("%*[^\t\n\r]");
大牛!这个看似很厉害,但是是放进去没有任何反应,该过还是过了。[/quote] 手误, 多谢了个符号. ^去掉. scanf("%*[\t\n\r]");[/quote] 这个可以,看似有点内涵,我得好好研究研究。
加载更多回复(24)

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧