0

Hi there im struggling to read a file and count the lines in it. I pass this code and im getting 1 more line than my file has.


` ifstream fin;
    
        fin.open("car.txt");
        
    // num of cars counted
    numberOffCars = 0;
    while (fin.good()) //while i have not reached the eof
    {
        getline(fin, line);
        numberOffCars++;
    }
    cout<<numberOffCars<<endl;
    fin.close();``

Thanks

J.J
  • 1
  • 1
  • 3
    Pop quiz: if the file is empty and has no lines in it, do you expect `fin.good()` to be true or false, immediately after opening the file? – Sam Varshavchik Oct 09 '20 at 02:50
  • Unrelated: Reconsider using exceptions where a simple `if` would do. `if (fin.fail()) { cout << "file not exist!" << endl; exit(1); }` and most of the code goes away. Rule of thumb: Only use exceptions when it simplifies the flow of the code and when the behaviour is uncommon enough to really be considered exceptional – user4581301 Oct 09 '20 at 02:52
  • 2
    Variant of [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons). In general, testing *before* doing is wasted effort. Do, test that you did, then use the results of the doing. With test, do, use, if the do fails you used bad data. – user4581301 Oct 09 '20 at 02:56
  • the thing is i have 5 lines in my .txt and the numberofcars(lines) counted always is one more than the lines. Not sure why is counting an empty line at the end and how could i just get the exact number of lines – J.J Oct 09 '20 at 03:44

2 Answers2

1

You can check if line is empty or not by simply using string::empty(). Here I have used std::ws to extract the leading whitespaces (if any).

Code :

#include <iostream>
#include <istream>
#include <fstream>
#include <string>

int main() {
    std::ifstream fin("car.txt");
    if (not fin) {
        std::cerr << "car.txt not found in working directory!";
        return -1;
    }
    std::string str;
    int n = 0;
    while (fin >> std::ws and std::getline(fin, str))
        if(not str.empty())
            ++n;
    std::cout << n;
}

This will ignore the empty line(s) (the ones having just whitespaces). Moreover, the main problem with your code was that you were using getline when EOF was just about to be reached. You needed to check the condition after reading the input.

Here, in my code, first getline will be evaluated and then fin (returned by getline) will be checked; it will tell us if last operation has succeeded or failed. In case EOF has been reached, it will fail, and consequently, the while loop will terminate.

Refer this thread for more information : Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong? I would like to quote a comment from it : just because we haven't reached the EOF, doesn't mean the next read will succeed.

brc-dd
  • 2,351
  • 3
  • 10
  • 25
0

it's because your code knows "EOF" after it reads "EOF" and numberOffCars++; so result of numberOffCars is 1 more than what you expect.

seenblee
  • 52
  • 4