c语言scanf缓冲区问题

今天在递归调用scanf函数获取输入的字符时发现的这个问题,之前也遇到过,现提出来记录一下。

测试用例如下:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    int n = 5;
    char c[n];
    for(int i = 0; i < n; ++i) {
        scanf("%c", &c[i]);
    }

    printf("-----------\n");
    printf("%s", c);
    return 0;
}

在写这个程序之前,我们期望的是c[n]字符数组中能够存储 abcde, 于是我们依次输入a,回车,然后输入b,回车,然会输入c,在此时你就会发现程序打印出字符数组c中的内容,并且运行完毕,用gdb调试工具单步执行的话,你会发现,在输入a,回车之后,c[0]中值是a,然后++i, 继续执行scanf("%c", &c[i])语言,而在这时程序不会提示你再输入字符,此时你查看c[1]中的字符是'\n',也就是说,我们输入的回车符保存在了缓冲区,scanf函数会直接读取该值。

解决方案,在scanf语句之后加入fpurge(stdin)语句,如下所示:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    int n = 5;
    char c[n];
    for(int i = 0; i < n; ++i) {
        scanf("%c", &c[i]);
        fpurge(stdin);
    }

    printf("-----------\n");
    printf("%s", c);
    return 0;
}

查看man fpurge的文档说明如下:

int fpurge(FILE *stream);

The function fpurge() erases any input or output buffered in the given stream. For output streams this discards any unwritten output. For input streams this discards any input read from the underlying object but not yet obtained via getc(3); this includes any text pushed back via ungetc(3).

也就是说,fpurge函数会直接删除当前缓冲区中的内容。

有同学可能会想使用fflush函数,这样是不行的,fflush的函数说明如下:

int fflush(FILE *stream);

The function fflush() forces a write of all buffered data for the given output or update stream via the stream's underlying write function. The open status of the stream is unaffected.

If the stream argument is NULL, fflush() flushes all open output streams.

从上面的说明可以看出,fflush是强制把缓冲区中数据输出到给定输出,在上面的例子中,在scanf函数之后调用fflush函数没有任何作用,因为此时还没有为后面的'\n'字符指定一个输出。


我的微博:http://weibo.com/caryaliu

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值