zoukankan      html  css  js  c++  java
  • C++ Primer 4th中第八章的一个错误 遗漏了cin.ignore

    第八章有个例子,非常简单,就是读入用户输入,赋给一个int,这里面有一个判断,就是如果用户输入的不是int,那么,cin就会变成invalid,里面就有condition state,于是我们可以catch这个state并clear,然后继续读入。

    但是书上给的例子有个错误,原来的程序是这样的:

    Code: Select all
    #include <iostream>
    #include <stdexcept>
    using namespace std;

    int main(int argc, char **argv)
    {
        int ival;
        // cout << "Begin state is: " << cin.rdstate() << endl;
        while (cin >> ival, !cin.eof()) {
            // cout << "Current Enter loop state is: " << cin.rdstate() << endl;

            if (cin.bad()) {
                // no catch so the terminate will be called
                throw runtime_error("IO Stream corrupted");
            }

            if (cin.fail()) {
                cerr << "bad data, try again: ";
                cin.clear(istream::failbit);
                // cout << "Current state is: " << cin.rdstate() << endl;
                continue;
            }

            // ok, print out this integer
            cout << "Input correct, your number is: " << ival << endl;
        }
    }


    这里有两个错误:

    (1)在Linux,g++环境下,cin.clear(istream::failbit)并不能清除cin的fail状态,尽管从clear函数的文档上来看应该是可以的。没办法,我改成了cin.clear()就OK了

    (2) 遗漏了cin.ignore这个句子或有相同效果的代码。这是因为cin的fail状态虽然被消除了,但是本次读入的错误的用户输入,比如用户输入的是一 个字符串,还存在于cin的buffer中,这样,下次循环cin >> ival照样出错,于是这样就形成了死循环。因为cin的buffer中始终存在着用户第一次输入的错误数据,于是while循环就一直继续着。

    后 来我加了这样一句: cin.ignore(100000, '\n'); 就OK了。可以看ignore的文档,代码的意思是ignore buffer中从一开始到第一个\n为止的所有字符,第一个参数故意写的很大,这是因为ignore的第一个参数表示ignore多少个字符,太小会导致 buffer中清除的不干净。

    修改后的代码如下:

    Code: Select all
    #include <iostream>
    #include <stdexcept>
    using namespace std;

    int main(int argc, char **argv)
    {
        int ival;
        // cout << "Begin state is: " << cin.rdstate() << endl;
        while (cin >> ival, !cin.eof()) {
            // cout << "Current Enter loop state is: " << cin.rdstate() << endl;

            if (cin.bad()) {
                // no catch so the terminate will be called
                throw runtime_error("IO Stream corrupted");
            }

            if (cin.fail()) {
                cerr << "bad data, try again: ";
                cin.clear();
                // Here cin's error condition state cannot be removed unless
                // we use cin.clear() directly
                // cin.clear(istream::failbit);

                // ignore current read wrong characters otherwise the loop
                // will go infinitely
                cin.ignore(11111111, '\n');
                // cout << "Current state is: " << cin.rdstate() << endl;
                continue;
            }

            // ok, print out this integer
            cout << "Input correct, your number is: " << ival << endl;
        }
    }



    顺便附上本章的另外一个练习代码,打印文本内容,使用了fstream:

    Code: Select all
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    using namespace std;

    int main()
    {
        ifstream input;
        vector<string> filelist;
        filelist.push_back("read.cc");
        filelist.push_back("fread.cc");
        filelist.push_back("dummy.cc");
        vector<string>::const_iterator it = filelist.begin();

        string s;
        // loop begin
        while (it != filelist.end()) {
            input.open(it->c_str());
            if (!input) {
                cout << "Open file " << *it << " failed, quit..." << endl;
                break;
            }

            cout << "Printing file " << *it << endl;
            while (getline(input, s))
                cout << s << endl;
            input.close();
            input.clear();
            ++it;
        }
    }
  • 相关阅读:
    Codeforces Round #649 (Div. 2) D. Ehab's Last Corollary
    Educational Codeforces Round 89 (Rated for Div. 2) E. Two Arrays
    Educational Codeforces Round 89 (Rated for Div. 2) D. Two Divisors
    Codeforces Round #647 (Div. 2) E. Johnny and Grandmaster
    Codeforces Round #647 (Div. 2) F. Johnny and Megan's Necklace
    Codeforces Round #648 (Div. 2) G. Secure Password
    Codeforces Round #646 (Div. 2) F. Rotating Substrings
    C++STL常见用法
    各类学习慕课(不定期更新
    高阶等差数列
  • 原文地址:https://www.cnblogs.com/super119/p/1996151.html
Copyright © 2011-2022 走看看