Reputation: 10152
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
Reputation: 8677
tacp's answer is good, but here are two things I would consider more idiomatic of C++/STL:
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);
}
streamiterator
/iterator constructorto 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
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