Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++, reading a file using ifstream

Tags:

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;
}

Please can you explain me, how following code snippet works? if (fin == NULL) { break; }

fin is a object on stack, not a pointer so it can not become NULL. I was unable to find overloaded operator== function in ifstream class. So I can not understand how this snippet works.

like image 298
Yoh0xFF Avatar asked May 21 '12 06:05

Yoh0xFF


People also ask

Does ifstream open a file?

Opening a File Either ofstream or fstream object may be used to open a file for writing. And ifstream object is used to open a file for reading purpose only. Following is the standard syntax for open() function, which is a member of fstream, ifstream, and ofstream objects.

How do I access a file in C++?

You can read information from files into your C++ program. This is possible using stream extraction operator (>>). You use the operator in the same way you use it to read user input from the keyboard. However, instead of using the cin object, you use the ifstream/ fstream object.

What is ifstream in C?

An ifstream is an input file stream, i.e. a stream of data used for reading input from a file. Because an ifstream IS an istream, anything you can do to an istream you can also do the same way to an ifstream.


3 Answers

The ifstream class has an operator void *() (or operator bool() in C++11). This is what is called when you test (fin == NULL).

Testing fin == NULL should be exactly the same as testing fin.fail().

like image 172
Greg Hewgill Avatar answered Sep 22 '22 10:09

Greg Hewgill


The base classes of istream and ostream have implicit conversion functions, which allow them to be used as a boolean value; in pre-C++11, the implicit conversion was to 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. The idiomatic way of writing the first loop would be to define a default constructor and an operator>> for Person, and then write:

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();
return fin ? EXIT_SUCCESS : EXIT_FAILURE;

.)

like image 24
James Kanze Avatar answered Sep 19 '22 10:09

James Kanze


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.

This code initialises an object of type Person from an input stream. 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>>.

like image 42
Konrad Rudolph Avatar answered Sep 20 '22 10:09

Konrad Rudolph