cwindowscltcc

getting early EOF when using specific sequence of bytes


I have this example program which just reads stdin and prints the characters as ints:

#include <stdio.h>

int main() {
    while (1) {
        char c = getchar();
        printf("%i\n", c);
        if (feof(stdin)) return 0;
    }
}

I've also generated input data using this Python script:

data = [71, 69, 71, 121, 118, 81, 51, 98, 51, 114, 119, 114, 108, 120, 33, 40, 22, 122, 125, 97, 88, 20, 81, 9, 22, 70, 70, 75, 89, 89, 90, 90, 88, 126, 20, 70, 9, 22, 77, 69, 71, 20, 70, 9, 22, 102, 78, 25, 103, 120, 124, 93, 102, 65, 30, 122, 96, 90, 20, 81, 9, 22, 91, 68, 31, 92, 105, 111, 20, 70, 9, 22, 99, 68, 124, 94, 97, 76, 17, 68, 89, 90, 20, 70, 9, 22, 76, 97, 91, 66, 105, 69, 20, 70, 9, 22, 16, 100, 20, 81, 9, 22, 77, 26, 93, 25, 111, 100, 64, 99, 20, 70, 9, 22, 73, 111, 79, 107, 102, 80, 127, 110, 28, 26, 108, 20, 70, 9, 22, 28, 93, 120, 75, 106, 124, 88, 76, 102, 78, 80, 24, 122, 20, 70, 9, 22, 121, 90, 78, 67, 73, 67, 20, 81, 9, 22, 90, 27, 76, 90, 20, 81, 9]

with open('data', 'wb') as f:
  f.write(bytes(data))

After compiling with either cl.exe from Visual Studio or tcc and running it:

cat data | ./out.exe

The output ends with:

9
22
77
-1

Which is only in like middle of the input data. Also, the output line count should be 165, but it is only 105 lines.

This example works perfectly fine on Linux, or on Windows with different inputs. Why does this fail on this specific data? What did I do wrong?


Solution

  • You can convert stdin to binary:

    #include <stdio.h>
    
    #ifdef _WIN32
    #  include <fcntl.h>
    #  include <io.h>
    #  define BINARY(fd) _setmode(fd, _O_BINARY)
    #else
    #  define BINARY(fd)
    #endif
    
    int main(void) {
        BINARY(0);
        int ch;
        while ((ch = getchar()) != EOF)
            printf("%i\n", ch);
        return 0;
    }
    

    Note that this is only a problem on nefarious operating systems that deliberately corrupt your data. See the #ifdef.