Reputation: 941
I'm trying to read a textfile which looks like this:
Gate
People
Crab
Motorbike
My code is:
string line;
vector<string> v_names;
ifstream myfile("c:/temp/test.txt");
if (! myfile.is_open()) {
cout << "Failed to open" << endl;
}
else {
cout << "Opened OK" << endl;
}
myfile.unsetf(ios_base::skipws);
unsigned line_count = count(istreambuf_iterator<char>(myfile), istreambuf_iterator<char>(), '\n');
while (getline(myfile, line)){
v_names.push_back(line);
}
If I want to get the size of my vector with v_names.size()
it gives back 0. If I call v_names[0]
I get the error "Vector subscript out of range"
What am I doing wrong?
Upvotes: 0
Views: 69
Reputation: 385385
unsigned line_count = count(istreambuf_iterator<char>(myfile), istreambuf_iterator<char>(), '\n');
Here you consumed all the data in your stream. Afterwards, there is no data remaining. So, there is nothing to loop over with getline
calls.
Since it is a file stream, you can "seek" back to the beginning of the file and begin consuming all the data again:
unsigned line_count = count(
istreambuf_iterator<char>(myfile),
istreambuf_iterator<char>(),
'\n'
);
myfile.seek(0, std::ios_base::beg);
myfile.clear();
while (getline(myfile, line)) {
v_names.push_back(line);
}
However, you have a problem, which is that your line_count
methodology is broken. The final line won't necessarily end in a '\n'
, leaving you off by one.
Mind you, as n.m. points out, counting the lines ahead of time would appear to be pointless anyway, as v_names.size()
will later give you the same information. Perhaps you can just remove that code and solve the problem that way.
Upvotes: 4
Reputation:
I don't see why you can't read the lines first, and count them afterwards.
while (getline(myfile, line)){
v_names.push_back(line);
}
auto line_count = v_names.size();
Then again, because the .size()
isn't walking away, just call it whenever you need to know how many names you have.
SIDE NOTE: counting the number of '\n'
s is not guaranteed to work all the time as the final line will not necessarily end with a newline.
Upvotes: 1