Grillteller
Grillteller

Reputation: 941

Reading a text file line by line leaves vector empty

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

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

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

user7881131
user7881131

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

Related Questions