vivekv80
vivekv80

Reputation: 119

read from file to array of structs within structs in C++

I have asked this question previously here and a similar question was closed.

SO based on a comment from another user, I have reframed my question:

In the first post, I was trying to read tha data from a file into an array with a struct.By using indata << p[i] and is >> p.fId, I was able to read values from data file into PersonId.

Now I want to try this:

struct PersonId
{
    int fId;
}; 

struct PersonData
{
    public:
        typedef PersonData* Ptr;
        PersonData();
        PersonId fId;
        istream& read(std::istream&);
};

istream& PersonData::read(std::istream& is) 
{
    is >> fId;
    return is;
}

istream& operator >> (istream& is, PersonData &p)
{
    // is >> p.fId;
    return p.read(is);
}

int main ()
{
    ifstream indata; // indata is like cin
    int i;
    indata.open("persons.txt", ios::in); // opens the file

    if(!indata) 
    { // file couldn't be opened
          cout << "Error: file could not be opened" << endl;
          exit(1);
    }

    int n = 5;

    PersonData* p;
    p = (PersonData*) malloc (n * sizeof(PersonData));


    while ( !indata.eof() )
    { 
        indata >> p[i];
        i++;
    }

    for(i = 0; i < n; ++i)
    {
        cout << "PersonData [" << i << "] is " << p[i] << endl;
    }
    return 0;
}

I want to use member function "read" to actually read values into structures defined by PersonData. My question:

  1. How to read the data from file into PersonId struct which is stored in the PersonData struct??

  2. While reading PersonData[i], I should see it have a struct PersonId with updated value.

I hope my questions are clear now?

Upvotes: 2

Views: 1263

Answers (2)

Tadeusz Kopec for Ukraine
Tadeusz Kopec for Ukraine

Reputation: 12413

OK, first some grumbling :-) You say what you want. You wrote how you try. Great. I guess result is not what you expected. But you didn't tell us what is the result you get and why you are disappointed with it. As I look at your code, it shouldn't compile. The problem is here:

istream& PersonData::read(std::istream& is) 
{
    is >> fId;
    return is;
}

I can't see any operator >> defined for PersonId type, and fId is of type PersonId. Am I right? Or maybe there is operator >> defined somewhere and you didn't just paste it into your question? My crystal ball is unclear. If I guessed properly, the solution is given by Dave Gamble:

istream& operator >> (istream& is, PersonId &p)
{
    is >> p.fId;
    return is;
}

You wrote "still getting errors in trying to access PersonData". I seems that this time Dave's crystal ball is also unclear, he can't say what problems you have. Neither can I. You have to either provide us details or send us better crystal balls. Maybe you missed his another advice "Also, fix the cout to use p[i].fId.fId." It means, that instead of writing

cout << "PersonData [" << i << "] is " << p[i] << endl;

you should write

cout << "PersonData [" << i << "] is " << p[i].fId.fId << endl;

There can be also another problem - you are not referring to std namespace members consequently - sometimes you write istream, and sometimes you write std::istream, you write endl instead of std::endl. Maybe Koenig's lookup works it out for you, I'm not good at it, but adding std:: prefix may help (of course if this is your problem).

Upvotes: 1

Dave Gamble
Dave Gamble

Reputation: 4174

You have:

istream& operator >> (istream& is, PersonId &p)
{
    is >> p.fId;
    return is;
}

missing, after struct PersonId;

You need this to make the is >> fId inside read() work correctly.

Also, fix the cout to use p[i].fId.fId.

Works great!

On a stylistic note, now you're in C++, don't use malloc, use new, and better yet, use a std::vector<>, which will take care of sizing for you.

Upvotes: 2

Related Questions