• 关于刷新输入缓存的问题


    一下是C++Primer中“流状态的查询和操作”的例题:

     1 #include<iostream>
     2 #include<limits>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int ival;
     8     while(cin >> ival, !cin.eof())        //必须输入两个文件结束符才可以结束输入???
     9     {
    10         if(cin.bad())        //input stream is corrupted; bail out
    11             throw runtime_error("IO stream corrupted");
    12         if(cin.fail())
    13         {
    14             cerr << "bad data,   try again   ";        //bad input
    15             cin.clear();        //warn the user        1
    16             cin.ignore(numeric_limits<int>::max(), '\n');    //ignore bad input,清空输入缓冲区的数据
    17             //也可以是cin.ignore(numeric_limits<streamsize>::max(), '\n');
    18             //同时上面ignore函数也可以用一个cin.get();代替
    19             //fflush(stdin);作用也同上,但是它是VC编译器的扩展功能,并不是C/C++标准里定义的,所以最好还是不用
    20             continue;        //get next input
    21         }
    22         // ok to process ival
    23         cout << ival << "\t";
    24     }
    25     cout << endl;
    26     return 0;
    27 }
    /*遇到问题:
    标号1处:原例题是cin.clear(istream::failbit);但是会出现一旦输入字符,
    就进入死循环的情况,即相当于clear函数没有执行,clear(flag)不是将制定条
    件状态flag设为有效吗??不解
    
    网上查找:WYYZAS的百度博客
      C/C++ 误区—— fflush(stdin)
    
    作者:antigloss 
    1.       为什么fflush(stdin) 是错的
    
    首先请看以下程序:
    
    程序代码
    
    #i nclude<stdio.h> 
    int main( void )
    {
        int i;
        for (;;) {
            fputs("Please input aninteger: ", stdout);
            scanf("%d", &i);
            printf("%d\n", i);
        }
        return 0;
    }
    
    这 个程序首先会提示用户输入一个整数,然后等待用户输入,如果用户输入的是整数,程序会输出刚才输入的整数,并且再次提示用户输入一个整数,然后等待用户输入。但是一旦用户输入的不是整数(如小数或者字母),假设 scanf 函数最后一次得到的整数是 2 ,那么程序会不停地输出“Please input an integer: 2”。这是因为   scanf("%d", &i); 只能接受整数,如果用户输入了字母,则这个字母会遗留在“输入缓冲区”中。因为缓冲中有数据,故而scanf 函数不会等待用户输入,直接就去缓冲中读取,可是缓冲中的却是字母,这个字母再次被遗留在缓冲中,如此反复,从而导致不停地输出“Please input an integer: 2”。
    
    也许有人会说:“居然这样,那么在 scanf 函数后面加上‘fflush(stdin);’,把输入缓冲清空掉不就行了?”然而这是错的!C和C++的标准里从来没有定义过fflush(stdin)。也许有人会说:“可是我用fflush(stdin) 解决了这个问题,你怎么能说是错的呢?”的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能(gcc3.2不支持),因为标准中根本没有定义 fflush(stdin)。MSDN 文档里也清楚地写着 fflush on input stream is anextension to the C standard (fflush 操作输入流是对C标准的扩充)。当然,如果你毫不在乎程序的移植性,用  fflush(stdin)也没什么大问题。以下是 C99 对 fflush 函数的定义:
    
    int fflush(FILE *stream);
    
    如果stream指向输出流或者更新流(updatestream),并且这个更新流
    最近执行的操作不是输入,那么fflush函数将把任何未被写入的数据写入stream
    指向的文件(如标准输出文件stdout)。否则,fflush函数的行为是不确定的。
    fflush(NULL)清空所有输出流和上面提到的更新流。如果发生写错误,fflush
    函数会给那些流打上错误标记,并且返回EOF,否则返回0。
    
    由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin) 是不正确的,至少是移植性不好的。
    
    2.       清空输入缓冲区的方法
    
    虽然不可以用 fflush(stdin),但是我们可以自己写代码来清空输入缓冲区。只需要在 scanf 函数后面加上几句简单的代码就可以了。
    
    程序代码
    
    /* C 版本 */
    #i nclude<stdio.h>
    int main( void )
    {
        int i, c;
        for (;;) {
            fputs("Please input aninteger: ", stdout);
            if ( scanf("%d",&i) != EOF ) { /* 如果用户输入的不是 EOF */
                /*while循环会把输入缓冲中的残留字符清空 */
                /* 读者可以根据需要把它改成宏或者内联函数 */
                /* 注:C99中也定义了内联函数,gcc3.2支持 */
                while ((c=getchar()) != '\n' && c != EOF ) {
                      ;
                } /*end of while */
            }
            printf("%d\n", i);
        }
        return 0;
    }
    
    /* C++ 版本 */
    
    
    #i nclude <iostream>
    #i nclude <limits>  // 为了使用numeric_limits
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main( )
    {
           int value; 
           for (;;) {
                  cout<< "Enter an integer: ";
                  cin>> value;
    /* 读到非法字符后,输入流将处于出错状态,
                  * 为了继续获取输入,首先要调用clear函数
                  * 来清除输入流的错误标记,然后才能调用
                  * ignore函数来清除输入缓冲区中的数据。 */          
                  cin.clear();
                  /*numeric_limits<streamsize>::max( ) 返回缓冲区的大小。
                  * ignore 函数在此将把输入缓冲区中的数据清空。
    * 这两个函数的具体用法请读者自行查询。 */
                  cin.ignore(std::numeric_limits<std::streamsize>::max( ), '\n' );
                  cout<< value << '\n';
           }
           return 0;
    }
    */
  • 相关阅读:
    css3 jQuery实现3d搜索框+为空推断
    simple_pool对象池——优化&lt;二&gt;
    微信支付v3开发(6) 收货地址共享接口
    一个简单的数据增量更新策略(Android / MongoDB / Django)
    cocos2dx 3.0rc怎样创建项目
    NYOJ 613 免费馅饼
    NLP系列(5)_从朴素贝叶斯到N-gram语言模型
    Swift开发图解入门
    java网络编程
    java多线程机制
  • 原文地址:https://www.cnblogs.com/sanghai/p/2766654.html
Copyright © 2020-2023  润新知