Why can Windows not read beyond the 0x1A (EOF) cha

2019-03-05 06:58发布

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 (chars / unsigned chars) 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 ints 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

2条回答
等我变得足够好
2楼-- · 2019-03-05 07:35

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

查看更多
Animai°情兽
3楼-- · 2019-03-05 07:59

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).

查看更多
登录 后发表回答