栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

对rewind(stdin)清除缓冲区功能的理解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

对rewind(stdin)清除缓冲区功能的理解

    我在网上找了不少资料,但对于rewind(stdin)为什么能够清空缓冲区似乎都没有比较详细的介绍。此贴就本人已搜查到的资料对此过程进行探讨。

    首先说一下rewind的定义:rewind 函数将与流 关联的文件指针 重新定位到文件的开头。  (该定义来自微软文档)

那么rewind(stdin)就是将stdin(标准输入流)的指针指向该流文件的开头。

  在进行接下来的讨论前,为了更好地理解,我们需要先了解一下缓冲区的部分知识:

系统缓冲区肯定是一个 buffer,用一个指针维护着这个buffer数据,当你读走一个数据时候,指针肯定后移了一个位置,但是数据还是在的,除非再有数据进入缓冲区覆盖掉这个位置上的数据。但是,这些维护buffer的指针值我们肯定访问不到,因此上说,读走一个数据后,即使是还存在的,我们也无法再访问了,等同于数据被读走后就不在了。(该观点来自网络上的资料)

如此,一些问题就解释得通了,例如执行以下代码

#include

int main()

{

    char a,b,c;

    scanf_s("%c", &a, 1);

    rewind(stdin);

    scanf_s("%c", &b,1);

    printf("%c",b);

    rewind(stdin);

    while (scanf_s("%c", &c, 1)==1)

    {

        printf("%c", c);

    }

}

如果输入

123456回车

789

程序只会输出789

这是因为将123456以及回车符’n’放进缓冲区后,scanf_s检索缓冲区,发现第一个数据符合格式%c后就将其读入,然后缓冲区的内部指针向后移一位,即将指针指向缓冲区中的2(注意,被读的字符‘1’并不会被删除或者清空,上文已经对此做出了解释)。如果没有rewind(stdin),那么下一个scanf就会读取2,并赋值给变量b,但如果有rewind(stdin),那么指针将被调向数据‘1’,再输入数据会将该数据覆盖掉,这也是为什么会输出7而不是2的原因。

  但为什么代码后面的循环没有把未使用的23456输出呢?这里需要区分一个观点:没清除≠没废弃,即使rewind(stdin)把指针指向文件的开头后并没有主动地清除后面的数据,但编译环境可能会自动废弃后面的数据。

  这里对此作出猜测:我们知道,缓冲区的刷新会让指针重新调向文件开头,如果这个“动作”没有伴随着数据的废弃,那么如果在第一次要求用户输入五个数据,用户也按要求输入5个数据1 2 3 4 5,第二次输入时就会自动读取上一次的数据,这显然是不合乎我们的认知的,因此,当指针指向文件开头时,编译环境会自动废弃后面的数据,这个规则使得上述问题得以解决。

  以上仅仅是我本人在有限的资料上综合自己的看法得出的结论,如果有错误的地方,还望大佬不吝赐教!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/511215.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号