关闭

stdin流、缓冲区

标签: stdin流缓冲区
353人阅读 评论(0) 收藏 举报
分类:

简介
简单来说,是一个专用的文件句柄。解释下句柄(句柄是操作系统在生成对象时分配给对象的唯一标识,句柄不同于指针。如果你得到一个对象的指针,那你就可以对此对象做一切操作!于是系统不给你指针,而是给用户一个加了限制的,用于跟踪对象的指针的标识——句柄!系统使用句柄对外提供服务就相对安全了,操作系统是通过API提供服务的,对于用户来说,句柄等同于对象指针,但实际上句柄和指针不是一回事!)
(stdin)就是标准输入的意思。就是以终端(计算机)为对象;即从键盘输入数据,运行结果到显示器屏幕上(就叫标准输入输出);再来解释下流的概念(流这个概念也解释不通,各种说法都有,反正我就暂理解为数据传输的字节序列吧)实际上,在内存中为每个数据流开辟一个内存缓冲区,用来存放流中的数据。当你向显示器输出数据时比如用(cout<<),现将这些数据送到程序中的输出缓冲区保存,直到缓冲区满了或遇到endl,就将缓冲区的全部数据送到显示器显示出来。在输入时,从键盘输入的数据先放在键盘缓冲区中,当按回车键时,键盘缓冲区中的数据输入到程序的输入缓冲区里。形成cin流。然后用提取预算符提取数据送给程序的有关变量。总之流是与内存缓冲区相对应的,或者说,缓冲区中的数据就是流。

接下来举几个例子说明:

#include<stdio.h>

int main()
{
    char a;
    char b;
    scanf("%c",&a);
    scanf("%c",&b);
    printf("%d %d",a,b);
    return 0;
}

当你在键盘按下q之后,就会打印出结果:
113 10 ( q 的ASCII码是130,换行键的ASCII码是10 )

出现这个原因就是scanf( ) 函数(你要是换成getchar()结果也一样)是从输入流缓冲区里读取值的,而并非是从键盘(也就是终端)缓冲区里读取,当按下q, q先放在键盘缓冲区里,当按下回车后,q以及“\n”进入到输入缓冲区里面,所以第一次q被取走后,第二次读入函数直接从缓冲区里把“\n”取走了。所以在读取成功后,就不会再从终端(键盘)读取,要解决这个的办法就是在第二次读取之前,清空缓冲区的残留数据。

使用fflush(stdin)或者rewind(stdio);都可以起到清空缓冲区的作用,这俩个函数都包含在stdio.h这个头文件中

修改后如下:

#include<stdio.h>

int main()
{
    char a;
    char b;
    scanf("%c",&a);
    fflush(stdin);

    scanf("%c",&b);
    printf("%c %c",a,b);
    return 0;
}

这时候你输入a回车,b回车;就能输出a b;这个结果。
(声明下,是在windows 平台下的vc++测试的程序;)

缓冲区
首先我们知道缓冲区的存在就是为了提高计算机的运算速度的(具体原因就是计算机对缓冲区的操作快于对磁盘的操作)

要知道缓冲区的类型有三个:全缓冲,行缓冲和不带缓冲:
1)全缓冲
在这种情况下,当填满标准I/O缓存后才进行实际I/O操作,全缓冲的典型代表是对磁盘文件的读写。

2)行缓冲
在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键时才进行实际的I/O操作。典型代表就是我在讲的(stdin)和标准输出(sdout)。

3)不带缓冲
也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。

大部分系统默认使用以下缓存类型:
1.标准出错是不带缓存的。
2.如果是涉及终端设备的流,则它们是行缓存的,否则是全缓存的。
由于ANSI C对stdin,stdout和stderr的缓存特征没有强行的规定,以至于不同的系统可能有不同的缓存特征。只能说目前主要的缓存特征是:stdin和stdout是行缓存;而stderr是无缓存的。

关于缓冲区的大小问题:
如果我们没有自己设置缓冲区的话,系统会默认为标准输入输出设置一个缓冲区,通常是4096个字节的大小。(这和计算机的分页机制有关,因为进程在计算机中分配内存使用的就是分页与分段机制,并且每个页的大小是4096个字节,因此通常情况下缓冲区的大小为4096个字节。)

最后一点就是关于缓冲区的刷新(就是清空):
下列情况会引起缓冲区的刷新:
1.缓冲区满时;
2.行缓冲区遇到回车时;
3.关闭文件;
4.使用特定函数刷新缓冲区。

参考资料:关于stdin流以及缓冲区浅谈

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:123351次
    • 积分:2608
    • 等级:
    • 排名:第14015名
    • 原创:135篇
    • 转载:13篇
    • 译文:0篇
    • 评论:11条
    文章分类
    最新评论