0

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?

Grillteller
  • 891
  • 10
  • 26

2 Answers2

4
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.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

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.

  • _"not every line will necessarily end with a newline"_ What else will they end with? Other than the very final line that is – Lightness Races in Orbit May 03 '17 at 09:31
  • @BoundaryImposition _"Other than the very final line that is"_ Exactly my point. One by off errors are not fun. The memory allocator may be nice and allocate blocks of powers of 2, but certain numbers cause certain run-time errors. –  May 03 '17 at 09:33
  • 1
    Sorry, what run-time errors do you expect here? What does the memory allocator have to do with it? The worst thing that can happen is one fewer line is "reported" in `line_count`, which is not going to result in overflowing access into `v_names`, if that's what you meant. – Lightness Races in Orbit May 03 '17 at 09:37
  • @BoundaryImposition You're right. Brain had an off-by-one error there. –  May 03 '17 at 09:52