Reputation: 3335
i was just testing some io safe checks with fstream and noticed i don't get any flags when seeking outside (i expected eof, but i realize flags are only set after io operations?) and when trying to read beyond the file size, i expected it to stop at eof, but it keeps on reading in from some unknown source. and lastly i noticed you don't even need to open a file. do i have to manually apply the math myself so it doesn't read past eof? and how/why/where is it reading past the file?
#include <iostream>
#include <fstream>
void checkErrors(std::ifstream& f){
std::cout<<"FLAGS: ";
if(f.good()) std::cout<<"good";
if(f.rdstate() & f.badbit) std::cout<<"badbit ";
if(f.rdstate() & f.eofbit) std::cout<<"eofbit ";
if(f.rdstate() & f.failbit) std::cout<<"failbit ";
std::cout<<std::endl;
}
int main(){
std::ifstream file;
// file.open("abc.txt"); // don't even have to open any file
file.seekg(100, file.beg); // can seek outside file
std::cout<<file.tellg()<<std::endl; // 100 (if open else) -1
checkErrors(file); // FLAGS: good (if open else) failbit
int size = 200;
char* data = new char[size];
file.read(data,size); // can read outside file
checkErrors(file); // FLAGS: eofbit failbit (if open else) failbit
for(int i=0; i<size; i++)std::cout<<data[i]; // PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\Windows\...
}
Upvotes: 2
Views: 2003
Reputation: 264391
why does ifstream read beyond eof?
I am sure it does not.
Are you asking why the bad()
is not true after you move beyond the end?
(even if no file is open) how to stop reading at eof?
If you attempt to read beyond the end of a file then you will get an error. Moving beyond the end by itself is not enough. But an attempt to access the data after you are beyond the end should cause an error.
Well you see to have a bug is here:
file.read(data,size); // can read outside file
for(int i=0; i<size; i++)std::cout<<data[i]; // PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\Windows\...
This should be written as:
if (file.read(data, size)) {
// If you attempt to read and it works then you can print out
// the data you read otherwise what is the point.
// Also notice you can't gurantee that you got `size` bytes.
// You should consult `gcount()` to get the number of characters read.
for(int i = 0; i < file.gcount(); ++i) {
std::cout << data[i];
}
}
Upvotes: 3