Possible Duplicate:
Why failbit set when eof on read? Is there a way out?
I am writing a little program and it was working brilliantly on Mac OS and Ubuntu (Unix...). The program has to read in a data file and separate the bytes (char
s / unsigned char
s) and memcpy()
them into floats. This would include the process of taking say the following four values, reading & left shifting them into a 32bit int
and then copying the int
s memory into a float
. Like so:
0x43 0x66 0x1A 0x79 -> read in int32 and memcpy() into float -> val = 230.103
As I said, this works fine for Unix, but Windows seems to interpret the char
0x1A
as an end of file (EOF) error and stop reading in data. Why does Windows do such a thing and not Unix? And how could I turn it off?
I even tried error handling by looking at the ifstream
itself and check if the EOL flag has been set. Then I would clear()
the ifstream
's error flags and continue reading (using get()
) but the damn thing always returns the same EOF / 0x1A
character and does not read in the next character.
EDIT: Added some code
ifstream input (PATH, ios::in);
if (input.is_open()) {
unsigned int counter = 0;
while (input.good()) {
BYTE byte;
byte = input.get();
printf("%i, ", byte);
counter++;
}
printf("\r%i, ", counter);
input.close();
} else {
printf("Can't open file!");
}
Any help is very much appreciated.
Max
With ifstream input (PATH, ios::in);
, you open the file in (the default) text mode. When a file is opened in text mode, the standard library performs platform-specific conversions on the data read from the file to map the platform's native format for text files into the view that C (and C++) has of a text file.
For unix-like systems (including Mac OSX and Linux), the native text format is the same as how C and C++ view a text, so no conversions are needed.
On Windows platforms, the line-endings have to be converted ('\n'
is converted to and from the character sequence CR LF
), and the EOF character that Windows defines (1A
) has to be interpreted.
On other systems, more extensive conversions might be needed (for example, if a text-file is specified as space-padded lines of exactly 80 characters, the implementation will have had to generate a '\n'
character itself after reading 80 characters, and it might suppress the trailing space characters in a line).
with ios::binary flag :
#include <iostream>
#include <fstream>
#include <windows.h>
int main()
{
std::ifstream input ("msg.txt", std::ios::binary );
if (input.is_open())
{
unsigned int counter = 0;
while (input.good())
{
BYTE byte;
byte = input.get();
printf("%d : %d \n", counter, byte);
counter++;
}
input.close();
}
}
Input data : 0x43 0x66 0x1A 0x79 0x68 0xAc
output :
0 : 48
1 : 120
2 : 52
3 : 51
4 : 32
5 : 48
6 : 120
7 : 54
8 : 54
9 : 32
10 : 48
11 : 120
12 : 49
13 : 65
14 : 32
15 : 48
16 : 120
17 : 55
18 : 57
19 : 32
20 : 48
21 : 120
22 : 54
23 : 56
24 : 32
25 : 48
26 : 120
27 : 65
28 : 99
29 : 32
30 : 255
In this example the data is read char by char, but you can adapt it to your use case using ifstream.read(buffer, buffersize)
.
By the way, this program was compiled with gcc on Windows7