自定义istream运算符始终返回false

问题描述

我遇到这样的问题,当我检查成功时,自定义重载>>运算符始终评估为“ false”。我认为这可能与我的istream实际上是重定向的ifstream(这意味着我将ifsteam传递给isteam)有关,尽管我不确定如何解决

这是代码段,已尽可能简化:

#include <istream>
#include <string>
#include <fstream>
#include <iostream>

class SomeClass {
public:
    SomeClass() = default;

    friend std::istream& operator>>(std::istream& is,SomeClass& random);

private:
    std::string my_str;
};

std::istream& operator>>(std::istream& is,SomeClass& random) {

    while(std::getline(is,random.my_str));

    if (random.my_str != "Hello World") {
        is.setstate(std::ios::failbit);
        return is;
    }

    is.setstate(std::ios::goodbit); //I didn't have this here before,put it in as a test
    return is;

}

bool io_parser(std::istream& input_stream) {

    SomeClass random;

    if (!(input_stream >> random))
        return false;

    return true;

}

int main(int argc,char* argv[]) {

    std::cout << argc << std::endl;
    std::istream* input_stream;

    std::ifstream input_file(argv[1]);

    if (!input_file.is_open()) {
        std::cout << "File Failed to open." << std::endl;
        return EXIT_FAILURE;
    }

    input_stream = &input_file;
    std::cout << io_parser(*input_stream) << std::endl;

    return EXIT_SUCCESS;

}

样本输入:

Hello World
Hello World
Hello World

无论如何,只要std :: getline()在while()中,它就不会起作用。如果单独使用,它会起作用。

解决方法

您有几个问题。

while(std::getline(is,random.my_str));

将始终保持读取和丢弃行,直到遇到错误。这可能是您想要的,但看起来很奇怪?在此循环之后,流将处于失败状态(通常设置为eof)。

is.setstate(std::ios::failbit);

正确设置fail位。但是

is.setstate(std::ios::goodbit);

不是将流返回到good状态的方法。 setstate将您指定的标志添加到当前流状态,因为goodbit实际上是0setstate(std::ios::goodbit)对流状态没有影响。要设置流状态,您需要调用clear

is.clear(std::ios::goodbit);

或为设置std::ios::goodbit,您可以不带任何参数调用:

is.clear();