fstream loads the last line of a file two times

I don't know why this program loads the last line of the file two times. The "ile" variable is equal to 1001 after the loop is over and it should be equal to 1000 since there's only 1000 lines with numbers(there's one that's empty).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(){
	fstream plik("cyfry.txt", ios::in);
	string bufer;
	int ile = 0;
	if (plik.good()){
		while (!plik.eof()){
			plik>>bufer;
			if (bufer.find_first_not_of("1234567890") == string::npos){
				ile++;
			}
		}
	}
	plik.close();
	cout<<ile;
	return 0;
}

This is how the last 11 lanes of the file cyfry.txt looks like
1
2
3
4
5
6
7
8
9
10
11
12
14868935
6015
24783163
15308
15960078
10238690
225206850
10769859
47656287
73685987
23606803
It actually reads the last line just once, but the eof() flag is not set first time.
Generally it is a bad idea to use eof() in a while loop condition.

Do this instead:
6
7
8
9
10
11
12
13
        while (plik>>bufer)
        {
            
            if (bufer.find_first_not_of("1234567890") == string::npos)
            {
                ile++;
            }
        }

Thanks for the help, it works now.
So if I use while (plik>>bufer) it will skip all the empty lines with only whitespaces in them?
Yes. bufer is of type string. This code plik>>bufer will skip any leading whitespace, then when it encounters a non-whitespace character, it starts to add each character to the string until either a whitespace character is read, or the end of file is reached. Note that whitespace in this context means any of ordinary space, or tab or newline.

If a string is successfully read, the resulting state of the stream plik is good. If no characters could be read into the string, then the stream state is fail. That means body of the while loop is executed only when the input operation was successful.

Sorry that sounds a bit complicated. Hope it makes sense.
Last edited on
It does make sense, thank you for explaining.
Topic archived. No new replies allowed.