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

聊聊C语言中scanf()怎么解决输入缓冲区残留‘/n’的问题
聊聊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;
}


------解决思路----------------------
其实我觉得用

char ch[2];
scanf("%s", ch);

就可以避免这个问题了。。
------解决思路----------------------
scanf("%*[^\t\n\r]");
------解决思路----------------------
    //scanf(" %c", &ch);         //方法3:(前边添加一个空格)消除上一个'/n'   有效


我一般都用这个办法
------解决思路----------------------
scanf(" %C", &ch); 

------解决思路----------------------
深入理解“流”这个概念。
理解后就知道可以“吸收”\n,可以忽略。

------解决思路----------------------
引用:
Quote: 引用:

scanf("%*[^\t\n\r]");


大牛!这个看似很厉害,但是是放进去没有任何反应,该过还是过了。聊聊C语言中scanf()如何解决输入缓冲区残留‘/n’的有关问题

手误, 多谢了个符号. ^去掉.
scanf("%*[\t\n\r]");
------解决思路----------------------
在每个最后不带\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.

------解决思路----------------------
#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.

------解决思路----------------------
while (getchar () != '\n')
continue;

经常用这个
------解决思路----------------------
可是不明白为什么 fflush(stdin)不行? 请指教!
------解决思路----------------------
引用:
Quote: 引用:

可是不明白为什么 fflush(stdin)不行? 请指教!

有图有真像!
聊聊C语言中scanf()如何解决输入缓冲区残留‘/n’的有关问题

好吧! 这是什么软件啊?
------解决思路----------------------
引用:
可是不明白为什么 fflush(stdin)不行? 请指教!
fflush 用于 stdin 的行为是不确定的 我记得是实现吧 简单的说 不可靠的做法
------解决思路----------------------
引用 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: 引用:

可是不明白为什么 fflush(stdin)不行? 请指教!
fflush 用于 stdin 的行为是不确定的 我记得是实现吧 简单的说 不可靠的做法

我记得在论坛里,有一篇帖子就是关于这个的, 好像说fflush(stdin)可以清楚缓存区, 
------解决思路----------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

可是不明白为什么 fflush(stdin)不行? 请指教!

有图有真像!
聊聊C语言中scanf()如何解决输入缓冲区残留‘/n’的有关问题

好吧! 这是什么软件啊?

上边用的eclipse cdt!如果不能说明问题,那么下边这个呢?
聊聊C语言中scanf()如何解决输入缓冲区残留‘/n’的有关问题

这些都是linux里面的软件吗? 那个画箭头的又是什么软件啊?呵呵。。 我明白你的意思, 这些软件都好高端啊!对于刚入门不久的新人来说!
------解决思路----------------------
引用:
Quote: 引用:

在每个最后不带\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,就得着大动干戈吗?显得有点麻烦了。您说呢?

我很高兴地告诉你,你理解错误:
每个最后不带\n的printf后面加fflush(stdout);
 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin);
 另外请检查scanf的返回值。
------解决思路----------------------
个人意见:最好的策略就是在scanf里面永远不用%c!
------解决思路----------------------
每个最后不带\n的printf后面加fflush(stdout);
每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin);
另外请检查scanf的返回值
------解决思路----------------------
楼主  是"\n"不是"/n"  ............
------解决思路----------------------
引用:
如果有了上下文,结果永远都是那么的意外:
聊聊C语言中scanf()如何解决输入缓冲区残留‘/n’的有关问题
ch[0]='/n'是不是很意外!


不意外 你说的情况我很了解 也清楚怎么解决 
我说的问题和这个没什么关系 
我只是在 反对 你对 scanf %c 只读取1个char的这个说法

闲话:你的 \n 还得写错多少次?? 我一开始以为你是手误

------解决思路----------------------
引用:
每个最后不带\n的printf后面加fflush(stdout);
每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin);
另外请检查scanf的返回值
fflush(stdin) 不可靠 楼主就是在说 fflush实现不了 
前面也有人告诉你了 

------解决思路----------------------
引用:
个人意见:最好的策略就是在scanf里面永远不用%c!
扯 不用%c 要读取1个char得怎么做?
getchar()? 
这个函数一样会读取空白字符

最好的策略是如果空白字符是无效字符 
用 scanf " %c" 空格%c读取 这样随便前面多少个多余的          \n\n\n\t\t\t 都不会被这个%c读取
------解决思路----------------------
引用:
Quote: 引用:

Quote: 引用:

可是不明白为什么 fflush(stdin)不行? 请指教!
fflush 用于 stdin 的行为是不确定的 我记得是实现吧 简单的说 不可靠的做法

我记得在论坛里,有一篇帖子就是关于这个的, 好像说fflush(stdin)可以清楚缓存区, 
fflush(stdin)在某些实现上的确可以清空缓存
但是 这个只是编译器扩展而已

标准上的说法是 fflush 用于 输出流 或 没有输入动作的更新流 
用于其他流[比如 stdin] 是未定义行为

------解决思路----------------------
引用:
题外话,scanf是不是一般只会在考试卷上出现,工程中用不到?要是这样的话,这个问题是不是可以先放这了?

scanf 可能用得到的机会的确是不多了
不过 他的兄弟函数
sscanf 和 fscanf 还是灰常给力的
用法和scanf区别不大
------解决思路----------------------
对scanf、printf这类函数,C程序员还是要做到“拳不离手,曲不离口”的。
------解决思路----------------------
聊聊C语言中scanf()如何解决输入缓冲区残留‘/n’的有关问题
------解决思路----------------------
引用:
Quote: 引用:

scanf(" %C", &ch); 


你这个属于加“ ”的!没有新意。。。聊聊C语言中scanf()如何解决输入缓冲区残留‘/n’的有关问题


没有新意?
有效,可移植!