C ++,使用ifstream读取文件

时间:2012-05-21 06:56:51

标签: c++ ifstream

class Person {
private:
    string firstName;
    string lastName;
public:
    Person() {}

    Person(ifstream &fin) {
       fin >> firstName >> lastName;
    }

    void print() {
       cout << firstName
           << " "
           << lastName
           << endl;
    }
};

int main() {
    vector<Person> v;
    ifstream fin("people.txt");

    while (true) {
        Person p(fin);
        if (fin == NULL) { break; }
        v.push_back(p);
    }

    for (size_t i = 0; i < v.size(); i++) {
       v[i].print();
    }

    fin.close();
    return 0;
}

请您解释一下,下面的代码片段是如何工作的? if(fin == NULL){break; }

fin是堆栈上的对象,而不是指针,因此它不能变为NULL。 我无法在ifstream类中找到重载的operator ==函数。 所以我无法理解这段代码的工作原理。

3 个答案:

答案 0 :(得分:5)

ifstream班级有operator void *() (or operator bool() in C++11)。这是您在测试(fin == NULL)时调用的内容。

测试fin == NULL应与测试fin.fail()完全相同。

答案 1 :(得分:3)

istreamostream的基类具有隐式转换 函数,允许它们用作布尔值;在pre-C ++ 11中, 隐式转换是void*

这种转换的结果从未被用作a 指针,像fin == NULL这样的代码显示极差 理解C ++和标准流。惯用的方式 编写第一个循环将是定义一个默认构造函数和一个 operator>> Person,然后写:

Person p;
while ( fin >> p ) {
    v.push_back( p );
}

(虽然我在做它:你真的应该测试它的返回值 fin.close(),如果失败则不返回0

fin.close();
return fin ? EXIT_SUCCESS : EXIT_FAILURE;

答案 2 :(得分:2)

这不是应该如何使用流。是的,这(不幸的是!)编译甚至做“正确”的事情。但是不要写这样的代码。编写此代码的人可能认为他们很聪明。

但是他们真正做的是通过引入一种新的非常规API来打破C ++程序员的期望,而没有真正的优势。

此代码从输入流初始化类型为Person的对象。不幸的是,通过这样做,代码放弃了在读取对象时测试错误的机会。这不好。一个对象有一个接受输入流的构造函数,它应该重载operator>>