B.K.
B.K.

Reputation: 10152

Writing file data into a class? C++

I have a class that looks like this:

class Test
{
public:
    Test() {}
    ~Test() {}

    //I kept these public for simplicity's sake at this point (stead of setters).
    int first_field;
    int second_field;
    int third_field;
    string name;
};

My .txt file looks like this:

1  2323   88   Test Name A1
2  23432  70   Test Name A2
3  123    67   Test Name B1
4  2332   100  Test Name B2
5  2141   98   Test Name C1
7  2133   12   Test Name C2

I would like to be able to read in each line from the file into a vector, so my current code for that looks like this:

#include "Test.h"
#include <fstream>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    ifstream file;
    vector<Test> test_vec;

    file.open("test.txt");
    if(file.fail())
    {
        cout << "ERROR: Cannot open the file." << endl;
        exit(0);
    }

    while(!file.eof())
    {
        string input;
        if(file.peek() != '\n' && !file.eof())
        {
            Test test;

            file >> test.first_field >> test.second_field >> test.third_field;
            getline(file, input);
            test.name = input;

            test_vec.push_back(test);
        }
    }

    return 0;
}

So, I'm stuck at the portion where I want to read in that data... I've tried input stream operator and it doesn't do anything; other options give me errors. I would also like to preserve the formatting if possible. What I want to do later is be able to sort that vector by different data fields in the class.

Any ideas?

EDIT: Problem has been solved and the code has been edited to reflect it. Thank you for all the help. :)

Upvotes: 2

Views: 258

Answers (2)

Nicu Stiurca
Nicu Stiurca

Reputation: 8677

tacp's answer is good, but here are two things I would consider more idiomatic of C++/STL:

Use operator >>

istream & operator>>(istream &in, Test &t)
{
  in >> t.first_field >> t.second_field >> t.third_field;
  getline(in, t.name);
  return in;
}

at which point reading in the file looks something like this

ifstream file("test.txt");
vector<Test> tests;
Test test;
while(file >> test) {
  tests.push_back(test);
}

Use streamiterator/iterator constructor

to make it super STL-idiomatic, use istream_iterator (don't forget #include<iterator>), and construct the vector from the iterators:

ifstream file("test.txt");
istream_iterator<Test> file_it(file), eos;
vector<Test> tests(file_it, eos);

PS: I upvoted for Noobacode for simple example code complete with sample input. That said, I would personally have preferred if you had left your original code as it was to make it easier for others to understand what your original problem was should they stumble unto this question.

Upvotes: 1

taocp
taocp

Reputation: 23624

One issue that should be solved before reading the file and parsing it into objects of your class is:

  Test test;
  test.push_back(test);

Your local variable test is an object of class Test, it hides your vector:

vector<Test> test;

When you do:

test.push_back(test);

you will have troubles. try to name your object to a different name.

Now you can think about how to process each line, what you may do is the following:

ifstream file;
file.open("test.txt");
int first_field, second_field, third_field;
string testName;
while (!file.eof()) {
   file >> first_field >> second_field >> third_field;
   getline(file, testName);
   cout << first_field <<" " <<  second_field << " " << third_field;
   cout << endl << testName <<endl;

    //you should set your constructor of Test to accept those four parameters
    //such that you can create objects of Test and push them to vector
}

Upvotes: 2

Related Questions