1

I have a binary file with the following repeating format: 6 float values + 3 unsigned char (byte`, integer value from 0 to 255) values.

I am parsing it like this:

FILE *file = fopen("file.bin", "r");
bool valid = true;

while(!feof(file)) {

  float vals[6];
  valid = valid && (fread((void*)(&vals), sizeof(float), 6, file) == 6);
  unsigned char a,b,c;
  a = fgetc(file); b = fgetc(file); c = fgetc(file); 

  (...)

}

This works fine for the first 30 iterations or so, but after that it simply stops parsing (way way before the end of the file).

What could be wrong?

I also tried parsing the unsigned char bytes with

fread((void*)&(a), sizeof(unsigned char), 1, file);
manatttta
  • 3,054
  • 4
  • 34
  • 72

1 Answers1

4

it simply stops parsing (way way before the end of the file).

You and the C Standard library are having a difference of opinion about where the end of the file is. ASCII character EOF (for DOS/Windows: decimal 26, hex 1A, aka Ctrl+Z, for Unix/Linux: decimal 4, hex 04, aka Ctrl+D) is a control character meaning "end of file". There's also the file length stored by the filesystem metadata.

The C stdio functions can operate in several modes: text, default, binary, and these control several behaviors:

  • Newline translations (implementation-defined): enabled in text mode, disabled in binary mode, default: ???
  • End of file: Implementation-defined, but usually EOF character in text mode, by filesystem file length in binary mode, default: ???

Since your file contains binary data, you should force binary mode by using "b" in the mode string to fopen, e.g.

FILE* file = fopen("file.bin", "rb");

When you do so, characters with value 26 are treated like any other byte and lose their "EOF" meaning.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720