0

我对以下简单代码有两个问题:

/*
test.cpp
© BS.
Example of creation of a class of a flow for which it is possible to assign the additional 
characters interpreted as separators.
11/06/2013, Раздел 11.7
*/
//--------------------------------------------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <algorithm>
#include <exception>
#include <string>
#include <vector>
using namespace std;
//--------------------------------------------------------------------------------------------------
class Punct_stream
// it is similar to istream flow, but the user can independently set separators.
{
private:
    istream& source; // source of chars
    istringstream buffer; // buffer for formatting
    string white; // whitespaces
    bool sensitive; // case sensitive
public:
    Punct_stream(istream& is): source(is), sensitive(true) {}
    void whitespace(const string& s) { white = s; } 
    void add_white(char c) { white += c; } 
    void case_sensitive(bool b) { sensitive = b; }
    bool is_case_sensitive() { return sensitive; }
    bool is_whitespace(char c); 
    Punct_stream& operator >> (string& s);
    operator bool(); 
};
//--------------------------------------------------------------------------------------------------
bool Punct_stream::is_whitespace(char c)
// is the c a whitespace?
{
    for(int i = 0; i < white.size(); ++i) if(c == white[i]) return true;
    return false;
}
//--------------------------------------------------------------------------------------------------
Punct_stream::operator bool()
// check the input result
{
    return !(source.fail() || source.bad()) && source.good();
}
//--------------------------------------------------------------------------------------------------
Punct_stream& Punct_stream::operator >> (string& s){
    while(!(buffer >> s)){ // try to read the data from the buffer
        if(buffer.bad() || !source.good()) return *this;
        buffer.clear();

        string line;
        getline(source,line); // read the line from the source

        // if necessary we replace characters
        for(int i = 0; i < line.size(); ++i)
            if(is_whitespace(line[i])) line[i] = ' ';
            else if(!sensitive) line[i] = tolower(line[i]);
            buffer.str(line); // write a string line to the stream
    }
    return *this;
}
//==================================================================================================
int main()
// entry point
try{
    Punct_stream ps(cin);
    ps.whitespace(";:,.?!()\"{}<>/&$@#%^*|~");
    ps.case_sensitive(false);
    cout << "Enter the words, please: ";
    vector<string> vs;
    string word;
    while(ps >> word) vs.push_back(word); // enter words
    sort(vs.begin(), vs.end()); 
    // we delete counterparts
    for(int i = 0; i < vs.size(); ++i) if(i == 0 || vs[i] != vs[i-1]) cout << vs[i] << endl;
}
catch(exception& e){
    cerr << e.what() << endl;
    return 1;
}
catch(...){
    cerr << "Unknown exception." << endl;
    return 2;
}

Punct_stream::operator bool() 函数中的检查对我来说不清楚:

return !(source.fail() || source.bad()) && source.good();

我的问题:

  1. 为什么作者检查“失败”和“坏”?为什么不只限制“好”检查?除非积极的“好”不自动暗示,“失败”和“坏”设置在“假”值中?

  2. 此外,经常在代码中编写这样的结构:cin >> x; while(cin){//...}

为什么作者没有如此类推:

Punct_stream::operator bool()
// check the input result
{
    // return !(source.fail() || source.bad()) && source.good();
        return source;
}

我显示的替代选项对我不起作用(Windows 崩溃),最好了解为什么,我错过了什么?

谢谢你。

4

1 回答 1

1

istream 对象包含一组表示其内部状态的位标志。其中,您感兴趣的是:

eofbit  End-Of-File reached while performing an extracting operation on an input stream.
failbit The last input operation failed because of an error related to the internal logic of the operation itself.
badbit  Error due to the failure of an input/output operation on the stream buffer.
goodbit No error. Represents the absence of all the above (the value zero).

它们的状态如下表所示

                                                good()  eof()   fail()  bad()
goodbit No errors (zero value iostate)          true    false   false   false
eofbit  End-of-File reached on input operation  false   true    false   false
failbit Logical error on i/o operation          false   false   true    false
badbit  Read/writing error on i/o operation     false   false   true    true

分别good()返回好位,eof()检查 eofbit,检查失败fail()位,令人惊讶的是,bad()返回坏位。因此,根据您在做什么,每个功能都可以在不同的设置中使用。

但是,在您的情况下,只需检查好位的正确性就足够了,因为当其他位都是错误的时,它是正确的。同时测试failbit 或badbit 是多余的。

来源:http ://www.cplusplus.com/reference/ios/ios/

编辑:其实我不太确定为什么你的替代方案行不通,因为它对我有用。你到底把什么数据传递给了程序?

于 2013-06-11T09:22:59.163 回答