博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
9、如何清空流及缓存
阅读量:6859 次
发布时间:2019-06-26

本文共 2333 字,大约阅读时间需要 7 分钟。

    如下小程序,如果输入错误,不是整形,则输入的这个数会留在缓存区,没有被type取到,type输出默认值或初始值或上次取得到的值(视初始化int type = 0这一句的位置,及编译器优化时,把它放到了那里,在如下程序中,GCC有可能把其提到循环的外面)。因为缓存区中有数据,所以cin不会等待用户输入,直接去缓存中读取,发现缓存中的数据不是整形,便把这个数据流在缓存区中,如此反复。这有点类似epollET模式,只要缓存中有数据,没有新的事件发生,则不会提示用户再去读,得用户把缓存中的数据全部读完才行。

void main( void )

{

while(1)

{

int type = 0;

cin >> type;

cout << type;

}

}

1、解决方案

1)错误的方法:通过fflush来刷新流。

int fflush(FILE *stream);

如果 stream 指向输出流或者更新流(update stream),并且这个更新流最近执行的操作不是输入,那么fflush 函数将把这个流中任何待写数据传送至宿主环境(host environment)写入文件。否则,它的行为是未定义的。

原文如下:

int fflush(FILE *stream);

If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

其中,宿主环境可以理解为操作系统或内核等。

由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin)  是不正确的,至少是移植性不好的。(VS支持,GCC不支持)

2)正确的解决方法:

1C版本

示例代码

ContractedBlock.gif
ExpandedBlockStart.gif
View Code
#include 
int main( void ) {
int i, c; for ( ; ; ) {
fputs("Please input an integer: ", stdout); scanf("%d", &i); if ( feof(stdin) || ferror(stdin) ) {
/* 如果用户输入文件结束标志(或文件已被读完), */ /* 或者发生读写错误,则退出循环 */ /* do something */ break; } /* 没有发生错误,清空输入流。 */ /* 通过 while 循环把输入流中的余留数据“吃”掉 */ while ( (c = getchar()) != '/n' && c != EOF ) ; /* 使用 scanf("%*[^/n]"); 也可以清空输入流, */ /* 不过会残留 /n 字符。 */ /*上述表达式是正则表达式,[^/n]表示非回车符*/ printf("%d/n", i); } return 0; }

2C++版本

示例代码

ContractedBlock.gif
ExpandedBlockStart.gif
View Code
#include 
#include
// 为了使用numeric_limits using std::cout; using std::endl; using std::cin; using std::numeric_limits; using std::streamsize; int main() {
int value; for ( ; ; ) {
cout << "Enter an integer: "; cin >> value; if ( cin.eof() || cin.bad() ) {
// 如果用户输入文件结束标志(或文件已被读完), // 或者发生读写错误,则退出循环 // do something break; } // 读到非法字符后,输入流将处于出错状态, // 为了继续获取输入,首先要调用 clear 函数 // 来清除输入流的错误标记,然后才能调用 // ignore 函数来清除输入流中的数据。 cin.clear(); // numeric_limits
::max() 返回输入缓冲的大小。 // ignore 函数在此将把输入流中的数据清空。 // 这两个函数的具体用法请读者自行查询。 cin.ignore( numeric_limits
::max(), '/n' ); cout << value << '/n'; } return 0; }

参考

1】 

转载地址:http://rrtyl.baihongyu.com/

你可能感兴趣的文章
20165324 前四周总结反思
查看>>
11.11评价
查看>>
第一章--第一节:环境搭建
查看>>
hdu 2665 划分树
查看>>
hdu 4251 划分树
查看>>
poj 1704 Georgia and Bob(阶梯博弈)
查看>>
JQuery中的$.ajax()
查看>>
js 幻灯片
查看>>
Keras序列模型学习
查看>>
[bzoj2809] 派遣
查看>>
Flask 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法
查看>>
PHP输出缓冲
查看>>
Windows2003上使用IIS7 Express使用FastCgi运行php
查看>>
安装程序时 “向数据库写入数据时发生错误!”
查看>>
图文:高春辉和他的网站梦
查看>>
网页之间的参数传递
查看>>
HTML5 做波形运动的小球
查看>>
初步学习Django-第四篇:views.PY文件详解
查看>>
OAuth2简易实战(四)-Github社交联合登录
查看>>
Netty学习大纲
查看>>