Ifstream Not Reading Eof Character

ifstream not reading EOF character

First thing is first, you shouldn't check like that. eof() doesn't return true until after a failed read. But you can do better (and easier)!

check the stream state with the implicit conversion to void* which can be used in a bool context. Since most of the read operations on streams return a reference to the stream, you can write some very consice code like this:

std::string line;
while(std::getline(currentfile, line)) {
// process line
}

Basically what it is doing is saying "while I could successfully extract a line from currentfile, do the following", which is what you really meant to say anyway ;-);

Like I said, this applies to most stream operations, so you can do things like this:

int x;
std::string y;
if(std::cin >> x >> y) {
// successfully read an integer and a string from cin!
}

EDIT: The way I would rewrite your code is like this:

string line;
unsigned long pos = 0;
int linenumber = 0;

ifstream curfile(input.c_str());

std::cout << "About to try to read the file" << std::endl;
while (std::getline(curfile, line)) {

std::cout << "Getting line " << linenumber << std::endl;
linenumber++;

// do the rest of the work with line
}

ifstream EOF executing early

It looks like you discard the data at the end of the file if the file size isn't an exact multiple of SIZE.

Also, even if the file size is an exact multiple of SIZE you'll be reading the last character and then eof() will not return true. Not until you've tried reading the next character will eof() return true, and that will trigger your error message, ERROR: EOF DETECTED.

More on that here:

Why is iostream::eof() inside a loop condition (i.e. while (!stream.eof())) considered wrong?

An alternative approach:

unsigned i = 0;

while(my_file >> file_buffer[i]) { // loop for as long as extracting succeeds
if(++i == SIZE) {
sendData(client_socket, file_buffer, i); // add a size parameter
// memset(file_buffer, 0, sizeof file_buffer); // why waste the time?
i = 0;
}
}

if(i) sendData(client_socket, file_buffer, i); // send the last part in the buffer

How does ifstream's eof() work?

-1 is get's way of saying you've reached the end of file. Compare it using the std::char_traits<char>::eof() (or std::istream::traits_type::eof()) - avoid -1, it's a magic number. (Although the other one is a bit verbose - you can always just call istream::eof)

The EOF flag is only set once a read tries to read past the end of the file. If I have a 3 byte file, and I only read 3 bytes, EOF is false, because I've not tried to read past the end of the file yet. While this seems confusing for files, which typically know their size, EOF is not known until a read is attempted on some devices, such as pipes and network sockets.

The second example works as inf >> foo will always return inf, with the side effect of attempt to read something and store it in foo. inf, in an if or while, will evaluate to true if the file is "good": no errors, no EOF. Thus, when a read fails, inf evaulates to false, and your loop properly aborts. However, take this common error:

while(!inf.eof())  // EOF is false here
{
inf >> x; // read fails, EOF becomes true, x is not set
// use x // we use x, despite our read failing.
}

However, this:

while(inf >> x)  // Attempt read into x, return false if it fails
{
// will only be entered if read succeeded.
}

Which is what we want.

why does ifstream read beyond eof? (even if no file is open) how to stop reading at eof?

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];
}
}

How to know if the next character is EOF in C++

istream::peek() returns the constant EOF (which is not guaranteed to be equal to -1) when it detects end-of-file or error. To check robustly for end-of-file, do this:

int c = file.peek();
if (c == EOF) {
if (file.eof())
// end of file
else
// error
} else {
// do something with 'c'
}

You should know that the underlying OS primitive, read(2), only signals EOF when you try to read past the end of the file. Therefore, file.eof() will not be true when you have merely read up to the last character in the file. In other words, file.eof() being false does not mean the next read operation will succeed.



Related Topics



Leave a reply



Submit