1

I am running into a strange situation. I use Dev C++ to write the following program:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
    FILE *fp;     // edited -- wrong type at first (File)
    unsigned char a, b;
    int c, count, res;      // added "res"
    short int d;

    fp = fopen("record.dat", "r");
    fseek(fp, SEEK_SET, 0);
    count = 0;    // edited -- wrong variable name at first

    res = fread(&a, 1, 1, fp);
    printf("a res = %d, errno %d\n", res, errno);
    while(count < 10) {
        count++;
        res = fread(&b, 1, 1, fp);    // added "res =" as mentioned in comment
        printf("b res = %d, errno %d\n", res, errno);
        res = fread(&c, 4, 1, fp);    // added "res =" as mentioned in 
        printf("c res = %d, errno %d\n", res, errno);
        res = fread(&d, 2, 1, fp);    // added "res =" as mentioned in 
        printf("d res = %d, errno %d\n", res, errno);
        res = fread(&a, 1, 1, fp);    // ** where problem starts
        printf("a res = %d, errno %d\n", res, errno);
    }

    fclose(fp);
}

The "record.dat" file is over 1MB in size, so I suppose the above program can get the data of the first 10 records without any issue (e.g. no need to handle EOF issue). However, when I compile the program in Dev C++ and run it, after reading 4 records, the fread() (marked by ** above) returns 0, and then subsequent fread() inside the while loop also return 0, meaning no data can be read. The stranger thing is all errno are 0, and when I use a g++ compiler in Linux to compile the same program, the program can read all (not just 10) of the records in the same file without any problem.

Is there anything I have missed? Thanks!

17
  • 2
    If this is your exact code, then you're missing res = before most of your fread()s, making the printf()s following them possibly misleading.
    – zenzelezz
    Commented Jul 28, 2015 at 14:03
  • THis is C code: why the c++ tag ?
    – Christophe
    Commented Jul 28, 2015 at 14:14
  • 2
    have you tried opening in binary mode ("rb") just in case c or d would contain the equivalent of an EOF marker ?
    – Christophe
    Commented Jul 28, 2015 at 14:19
  • 1
    @Christophe Thanks for changing the tag. "rb" is the fix, I changed the parameter in fopen() from "r" to "rb", deleted the original executable and then re-compiled, it solved the problem! Thank you very much! Commented Jul 28, 2015 at 14:29
  • 1
    @melpomene: If the OP went to the trouble of modifying Dev-C++'s options to invoke a C compiler, he didn't mention it. Furthermore, his control is "a g++ compiler in Linux" and he tagged the question c++. Seems like a pretty safe bet to me. Commented Jul 28, 2015 at 14:42

1 Answer 1

2

If you're reading a binary file, you should open it with "rb", not "r". Otherwise you get (platform specific) "text mode" handling. On Linux this doesn't change anything, but on Windows this will translate CR/LF (0D 0A) to '\n' and may also interpret ^Z as the end of the file.

You can confirm this by looking at a hex dump of the file: If your program mysteriously stops reading at 1A, this is the problem.

1
  • Thank you very much, I believe your answer pinpoints the problem I was facing. There was a "1A" when reading the file to the integer c in run #4 of the while loop. Commented Jul 28, 2015 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.