简体   繁体   English

C ++,使用ifstream读取文件

[英]C++, reading a file using 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;
}

Please can you explain me, how following code snippet works? 请问您能解释一下我的代码片段如何工作? if (fin == NULL) { break; if(fin == NULL){break; } }

fin is a object on stack, not a pointer so it can not become NULL. fin是堆栈上的对象,而不是指针,因此它不能变为NULL。 I was unable to find overloaded operator== function in ifstream class. 我无法在ifstream类中找到重载的operator ==函数。 So I can not understand how this snippet works. 所以我无法理解这段代码的工作原理。

The ifstream class has an operator void *() (or operator bool() in C++11) . ifstream类有一个operator void *() (或C ++ 11中的operator bool() This is what is called when you test (fin == NULL) . 这是测试时调用的(fin == NULL)

Testing fin == NULL should be exactly the same as testing fin.fail() . 测试fin == NULL应该与测试fin.fail()完全相同。

The base classes of istream and ostream have implicit conversion functions, which allow them to be used as a boolean value; istreamostream的基类具有隐式转换函数,允许它们用作布尔值; in pre-C++11, the implicit conversion was to void* . 在pre-C ++ 11中,隐式转换是void*

It was never the intent that the result of this conversion be used as a pointer, and code like fin == NULL shows an extremely poor understanding of C++ and the standard streams. 从来没有意图将此转换的结果用作指针,并且像fin == NULL这样的代码表明对C ++和标准流的理解非常差。 The idiomatic way of writing the first loop would be to define a default constructor and an operator>> for Person , and then write: 编写第一个循环的惯用方法是定义一个默认构造函数和一个operator>> for Person ,然后编写:

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

(And while I'm at it: you really should test the return value of fin.close() , and not return 0 if it fails: (当我在它时:你真的应该测试fin.close()的返回值,如果失败则不返回0

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

.) 。)

This isn't how streams are supposed to be used. 这不是应该如何使用流。 True, this (unfortunately!) compiles and even does the “right” thing. 是的,这(不幸的是!)编译甚至做“正确”的事情。 But don't write code like this. 但是不要写这样的代码。 Whoever wrote this code probably thought they were clever. 编写此代码的人可能认为他们很聪明。

But what they really did was break the expectations of C++ programmers by introducing a new, unconventional API, with no real advantages. 但他们真正做的是通过引入一种新的非传统API来打破C ++程序员的期望,而没有真正的优势。

This code initialises an object of type Person from an input stream. 此代码从输入流初始化Person类型的对象。 Unfortunately, by doing this, the code forgoes the opportunity to test for errors while reading the object. 不幸的是,通过这样做,代码放弃了在读取对象时测试错误的机会。 This isn't good. 这不好。 An object should not have a constructor accepting an input stream, it should overload operator>> . 对象应该有一个构造函数接受输入流,但是应当过载operator>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM