- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C语言中输入输出流与缓冲区的深入讲解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
缓冲区 又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区.
缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区.
原理介绍
1、为什么要引入缓冲区 。
例如,我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度.
又比如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情.
现在您基本明白了吧,缓冲区就是一块内存区, 它用在输入输出设备和CPU之间,用来缓存数据 。它 使得低速的输入输出设备和高速的CPU能够协调工作 ,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作.
2、缓冲区的类型 。
缓冲区分为三种类型:全缓冲、行缓冲和不带缓冲.
1) 全缓冲 。
在这种情况下,当 填满 标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是 对磁盘文件的读写 .
2) 行缓冲 。
在这种情况下,当在输入和输出中遇到 换行符 时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等 按下回车键换行 时才进行实际的I/O操作。典型代表是 标准输入(stdin) 和 标准输出(stdout) .
3) 不带缓冲 。
也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来.
3、缓冲区的大小 。
如果我们没有自己设置缓冲区的话,系统会默认为标准输入输出设置一个缓冲区,这个缓冲区的大小通常是 512个字节 的大小.
缓冲区大小由 stdio.h 头文件中的宏 BUFSIZ 定义,如果希望查看它的大小,包含头文件,直接输出它的值即可:printf("%d", BUFSIZ),
缓冲区的大小是可以改变的,也可以将文件关联到自定义的缓冲区,详情可以查看 setvbuf()和 setbuf() 函数.
4、缓冲区的刷新(清空) 。
下列情况会引发缓冲区的刷新: 缓冲区满时 ; 行缓冲区遇到回车时 ; 关闭文件 ; 使用特定函数刷新缓冲区 .
5、结合缓冲区谈谈C语言getchar()、getche()、getch()的区别 。
先来看一下 getchar() ,其原型为: int getchar(void),
当程序调用getchar()函数时,程序就等着用户按键, 用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止(回车字符也放在缓冲区中) 。当用户键入回车之后,getchar()函数 才开始从键盘缓冲区中每次读入一个字符 。也就是说, 后续的getchar()函数调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完后,才重新等待用户按键 。打个比方,键盘缓冲区就像是一条水管连着你的程序,程序调用getchar()函数用户输入字符就相当于往水管里注水,这个水注多少取决于你输入多少,当你按回车停止注水时,getchar()函数才会开始从键盘缓冲区,也就是我们的水管里取水,那每次只会读一个字符也就是每次取一定量的水,当你在这之后继续调用getchar()函数时,会接着在水管里取上次没用完的水,因为你的水管没清空(缓冲区的刷新),那这个阶段就不用你再输入了,因为一调用getchar()函数就有水可取嘛,直到水管里没水了,你还调用getchar()函数,那这个时候你就得注水了也就是程序会等你按键.
通俗一点说,当程序调用getchar()函数时,程序就等着用户按键,并等用户按下回车键返回。期间按下的字符存放在缓冲区,第一个字符作为函数返回值。继续调用getchar()函数,将不再等用户按键,而是返回您刚才输入的第2个字符;继续调用,返回第3个字符,直到缓冲区中的字符读完后,才等待用户按键.
getchar()函数的执行就是采用了行缓冲。第一次调用getchar()函数,会让程序使用者(用户)输入一行字符并直至按下回车键 函数才返回。此时用户输入的字符和回车符都存放在行缓冲区。再次调用getchar()函数,会逐步输出行缓冲区的内容.
请看下面一个例子:
运行结果如下:
再把程序做微小改变,你再看看,加深理解:
运行结果:
上面第二次打印时不是2而是空格,你应该想到为什么了吧?
好,我们再来看一个例子:
运行结果:
getchar()函数是从 输入流缓冲区 中读取数据的,而不是从 键盘(终端)缓冲区 读取。当读取遇到回车(\n)结束时,这个'\n'会一起读入到输入流缓冲区的, 所以第一次接收输入时取走字符后会留下字符\n,这样第二次getchar()直接从缓冲区中把\n取走了 ,显然读取成功了,所以不会再从终端读取!其实这里的 10恰好是回车符 !这就是为什么这个程序只执行了一次输入操作就结束的原因! 。
getch()和getche()函数 。
在TC2.0时代,C程序员总是喜欢在程序末尾加上getch() ,来实现程序运行完了暂停不退出的效果。如果不这样做,在TC2.0的环境中Ctrl+F9编译并运行后会立即退出程序,根本来不及看到结果。这时如果要看结果,就要按Alt+F5回到DOS环境中去,很麻烦。而如果在程序的结尾加上一行getch();语句,就可以省掉回DOS看结果这个步骤,因为程序运行完了并不退出,而是在程序最后把屏幕停住了,按任意键才退出程序.
实际上, getch() 的作用是从键盘 接收一个字符,且不带回显 。就是说, 你按了一个键后它并不在屏幕上显示你按的什么,而继续运行后面的代码 ,所以在C语言中可以用它来实现“按任意键继续”的效果,即程序中遇到getch();语句,就会停下来,等你按任意键,它接收了这个字符键后再继续执行后面的代码。这跟上面在Windows下用的system(“PAUSE")功能一样,但却不会在屏幕上显示(即不会有”按任意键继续“的提示),这样,利用getch()无回显的特性,不管你按什么键,都不会在屏幕上留下痕迹,使你的界面达到美观效果。.
getche() 和getch()很相似,它也需要引入头文件conio.h,它们之间的区别就在于:getch()无回显,getche()有回显.
下面看一个例子:
首先这是个连续5次的循环来实现5次停顿,等待你输入。编译并运行这个程序,假设输入的是abcde,那么屏幕上显示的结果也是abcde,这个abcde并不是在ch=getch();中输出的。把printf("%c",ch);这行语句去掉,就会发现按5次任意键程序就结束了,但屏幕上什么都没有显示.
你可以把代码中的getch()换成getche()看看有什么不同。如果还是输入abcde,那么屏幕上显示的结果是aabbccddee,我们把printf("%c",ch);这行语句再去掉,显示的结果就是abcde了,说明程序在执行ch=getche();这条语句的时候就把我们输入的键返回显示在屏幕上, 有无回显就是它们的唯一区别 .
总结 。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:https://www.jianshu.com/p/bd4fc453215b 。
最后此篇关于C语言中输入输出流与缓冲区的深入讲解的文章就讲到这里了,如果你想了解更多关于C语言中输入输出流与缓冲区的深入讲解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这个问题在这里已经有了答案: Possible to make an event handler wait until async / Promise-based code is done? (2
我经常有多个运行的进程(R,Python,eshell/shell),对于每个进程,我经常都有一个相关的脚本,可以从中发送摘要。为此,我通常将每个框架垂直地分成两个窗口,以便脚本文件(例如.py)位于
如何修改 emacs 在关闭缓冲区后选择要显示的缓冲区的方式? 当我有多个列显示相同的缓冲区,然后在其中一个缓冲区中打开另一个文件,然后关闭新打开的缓冲区时,它不会切换回前一个缓冲区,而是切换到另一个
如何将 ex 命令复制到剪贴板或粘贴到缓冲区? 在 Windows 上使用 gvim。 最佳答案 windows剪贴板可以通过the buffer + 访问.因此,可以使用 + 将剪贴板粘贴为前命令。
在 javascript 中如何以比以下更简单的方式获取 b 缓冲区? var num=6553599 var a = new Buffer(4); a.writeInt32LE(num)
每次我在 Google 上搜索有关 OpenGL 编程的文章时,我都会找到一些文章,但似乎所有文章都提到了着色器和缓冲区。那些是什么?你能解释其中的一些吗: 深度缓冲区 模板缓冲区 像素着色器 帧缓冲
我有java考试,当我学习时,我看到了这个练习,我尝试解决它,但我发现一些困难,所以请帮助我考虑实用程序中方法的以下注释、 header 和部分代码名为 Atbash 的加密类。 /**
每次我在 Google 上搜索有关 OpenGL 编程的文章时,我都会找到一些文章,但似乎所有文章都提到了着色器和缓冲区。那些是什么?你能解释其中的一些吗: 深度缓冲区 模板缓冲区 像素着色器 帧缓冲
对于每个属性使用跨步顶点缓冲区与紧密打包缓冲区有何优缺点?我的意思是例如: 步幅:xyzrgb xyzrgb xyzrgb 紧:xyzxyzxyz rgbrgbrgb 乍一看,使用步幅时您似乎可以轻松
我正在尝试将文本文件中每行的数字读取到 ArrayList 中。当我执行以下函数时,它总是跳过最后一个元素。有人可以帮我吗?因为我在这里没有遇到问题,因为它读取直到缓冲区为空,所以他应该在到达 Fil
#include #include int main () { time_t time_raw_format; struct tm * ptr_time; char *buff
基本上我有一个包含不同类型数据的自定义结构。例如: typedef struct example_structure{ uint8_t* example_1[4]; int example_2[4];
我之前的列表实现是一个简单的 LinearLayout,位于一个装满我的项目的 ScrollView 中。 我切换到 ListView 的 Android 实现以简单地使用 CursorAdapter
我想创建一个可变长度的输入事件窗口/缓冲区,当它接收到额外的事件时会变长。 这是为了实现“键入时搜索”功能。我想捕获点击,但为了不给服务器造成压力,我想明智地进行服务调用。 我想到的逻辑是缓冲击键,从
我想将 yuv420P 像素写入缓冲区而不是二进制文件。假设我在指针中存储了 luma 、 Cb 和 Cr。 luma = output_pixel.luma; cb = output_pixel.c
我想在 Go 中构建一个支持多个并发读取器和一个写入器的缓冲区。所有写入缓冲区的内容都应由所有读者读取。允许新读者随时加入,这意味着已经写入的数据必须能够为迟到的读者回放。 缓冲区应满足以下接口(in
本文转载自微信公众号「小明菜市场」,作者小明菜市场。转载本文请联系小明菜市场公众号。 前言 Java NIO 需要理解的主要有缓冲区,通道,选择器,这三个主要的部分。 基础
一 点睛 NIO,可以称为 New IO 或 Non Blocking IO,是在 JDK 1.4 后提供的新 API。传统的I/O 是阻塞式的 I/O、面向流的操作;而 NIO 是非阻塞 I/O 、
我正在寻找一种切换到包含搜索文本的缓冲区的方法。 例如。如果我打开了 100 个缓冲区,我想切换到一个包含 'fooBar = 1' 的缓冲区 最佳答案 我写了一个 Vim 插件来做到这一点:buff
我正在尝试将提取的视频帧(我使用 ffmpeg)推送到 FFMPEG 缓冲区中。我已经查看了 ffmpeg 的缓冲区源文件,例如 buffersrc.c 和 fifo.c,以确定我是否可以这样做,但我
我是一名优秀的程序员,十分优秀!