Maria
Maria

Reputation: 13

Read objects from file c++

I want to read 3 objects from file. For example, in main I wrote:

ifstream fis;
Person pp;
fis >> pp;
Person cc;
fis >> cc;
Person dd;
fis >> dd;

The problem is that for every Person, it reads me 3 objects. I need to create an array of objects?

ifstream& operator>>(ifstream&fis, Person &p){

    fis.open("fis.txt", ios::in);
    while (!fis.eof())
    {
        char temp[100];
        char* name;
        fis >> temp;
        name = new char[strlen(name) + 1];
        strcpy(name, temp);
        int age;
        fis >> age;


        Person p(name, age);
        cout << p;
    }

    fis.close();
    return fis;
}

Upvotes: 1

Views: 1180

Answers (2)

xmoex
xmoex

Reputation: 2702

Problem:

You're opening and closing the input stream inside of your operator>>. So everytime it is executed it opens your file at the beginning, then reads to the end and closes the file again. At the next call it starts all over again.

Explaination:

The used input stream keeps track of it's current reading position. If you reinitialize the stream in every call, you reset the position in the file thus starting at the beginning again. If you're interested you can also check the position with std::ifstream::tellg().

Possible solution:

Prepare the input stream outside of operator>>, then just read one dataset per call. After all reading is done close the file on the outside.

Example:

Calling code:

#include<fstream>

// ... other code

std::ifstream fis;
Person pp, cc, dd;

fis.open("fis.txt", std::ios::in); // prepare input stream

fis >> pp;
fis >> cc;
fis >> dd;

fis.close(); // after reading is done: close input stream

operator>> code:

std::ifstream& operator>>(std::ifstream& fis, Person &p)
{
    // only read if everything's allright (e.g. eof not reached)
    if (fis.good())
    {
        // read to p ...
    }

    /*
     * return input stream (whith it's position pointer
     * right after the data just read, so you can start
     * from there at your next call)
     */
    return fis;
}

Upvotes: 5

janisz
janisz

Reputation: 6371

Before you use operator>> you should prepare stream that you want to read from.

ifstream fis;
fis.open("fis.txt", ios::in);
Person pp;
fis >> pp;
Person cc;
fis >> cc;
Person dd;
fis >> dd;
fis.close();

Your code should look like this.

ifstream& operator>>(ifstream&fis, Person &p) {
    char temp[100];
    char* name;
    fis >> temp;
    name = new char[strlen(name) + 1];
    strcpy(name, temp);
    int age;
    fis >> age;
    Person p(name, age);
    cout << p;
    return fis;
}

Consider adding additional checking if stream is not empty and using strings instead of char*

Upvotes: 2

Related Questions