现在的位置: 首页 > 综合 > 正文

【c语言】清空缓存 的问题

2017年11月28日 ⁄ 综合 ⁄ 共 1778字 ⁄ 字号 评论关闭

我们使用函数向某个文件从当前流标签所在位置,读取n个字符。我们也会使用函数想文件的某个流位置写如n字符。但是,当这种写的动作小、而频繁。每次写又必须反映到硬盘上,也就是说需要频繁的操作硬盘,写一些小的更改,这是非常耗损效率。所以自然我们想到了,我们设立一个缓冲区,将那些要写如的数据先写到缓冲区中,当缓冲区满,或者其他情况发生的是否,我们在一起将他们写入到硬盘上。这样可以大大提高应用程序读写文件的速度。
 
这就是为什么需要缓冲,根本原因我认为是磁盘等外设的数据还和内存的速度相差甚远,所以我们不希望由于操作外设的原因让本来很快的内存和CPU跟着一起慢,我们想的办法:一是异步写(但这有时候不能符合应用要求),二就是缓冲读写。

 

而我们通常所理解的就是,read体系,就是那种无缓冲读写,不管是读还是写,调用这个体系的函数,会马上启动一次外设操作,读取数据或者写入数据。而fread体系则,使用了缓冲读写的方式,一定时间才调用read体系的函数。

 

清空stdin中的缓存

int c;

while((c = getchar()) != EOF && c != '\n');

会把缓存清空,但是会遗留下'\n'  (10)

读取时,可以使用 scanf("%[^\n]",c);来空过\n。

或 scanf("\n%d",c);

 

 

失败的解决方案:

1,

while(!feof(stdin)){

  getchar();

}

结果:程序会卡在这段,永远出不了while循环。

因为feof(FILE* file )函数必须等下一次读取不到数据使,才会返回非0;如读取空文件时,直接用feof(file)返回的是0,而用一下

fread()函数后,虽然什么都没有读到,但是feof(file)就返回非0了;

所以就会造成虽然到了结尾了,但是feof(stdin)返回的还是0,然后程序就会卡在getchar(),等待输入。

 

2,

fflush(stdin);

//使用后无效,查了一下,此函数不是标准函数,VC编译器可以使用,但是其他的编译器如gcc是不支持的(注:fflush(stdout)是标准函数)

linux下是刷新缓存,在VC下是清除缓存 

 

3,

while((c = getchar()) != EOF && c != '\n');此时缓冲区第一个字符是'\n'。

scanf("%*[\n]%d",c);  此时c读取的是\n,没有读到后面的输入,导致程序错误。

 

没想明白为什么,%【\n】不是读到第一个非\n时停止吗,加上星号忽略这个,然后%d就可以读到输入。但是结果不对,请大侠解答谢谢!

 

4,

用setbuf(stdin, NULL);清空缓存

setbuf的函数原型是

void setbuf(FILE*stream
,char *buf);

 

事实上,read体系也有自己的缓冲机制,但是我们可以通过设置(open函数中DIRECT标志),放弃这种方式。
我们可以说,fread是在用户应用程序空间中,自己建立了一个缓冲机制,这种缓冲机制和内核read的缓冲机制并不冲突。
事实上,当我们使用read体系的是否,我们放弃了应用程序空间中的缓冲机制,但是如果不设置DIRECT标志,内核中的缓冲机制依然存在。
 
我们还有一种特殊的读写应用程序,叫着自缓冲读写,其实fread就是这样一种方式。只是它没有放弃内核的缓冲机制。但是对于复杂应用程序,例如数据库,这种对读写效率要求高的地方,他们使用了自己定义缓冲机制并且毅然放弃了内核的缓冲方式,为什么呢?因为内核缓冲方式,对缓冲数据何时应该存入到硬盘上,那些数据应该留下来更久没有应用背景相关的信息,所以它所出来的决策,通常是盲目的。但是,如果应用程序自己设置这种缓冲,可以很大程度上弥补这一问题。
 
 
缓冲I/O绝对有它的好处,这种机制的使用不仅在用户空间中,也在内核实现时会使用。当然有是否我们为了最求某些特别的需求,会使用直接I/O方式。当然事实上,这种I/O方式,与缓冲与否不是对立的。但是往往这样做了之后,缓冲就不够。我们要使用直接I/O要慎重考虑,你应用程序的需求,例如,你需要存取大块数据。这个是否“多拷贝”无疑是一个问题。 其中取舍需要仔细考虑、权衡。 

 

http://www.cnblogs.com/blogoflee/archive/2012/02/01/2334433.html

抱歉!评论已关闭.