-1

I'm trying to read the hex values from an image file using C. In Linux, this code works fine, but with Windows it reads only the first 334 bytes and I don't understand why.

The code to read the file is:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>    
void readHexFile(char* path) {
        FILE *fp;

        if ((fp = fopen (path, "r")) != NULL) {
            struct stat st;
            stat(path, &st);                

            int i;
            int ch;
            for (i = 0; i < st.st_size; i++) {
                ch = fgetc(fp);             
                printf("%x ", ch);
            }

            fclose(fp);
        }
        else {
            return NULL;
        }
}

st.st_size comes from <sys/stat.h> package and contains the right value (the size, in bytes, of the image file)

This image show what my program outputs, and the actual binary content of the file it is reading:

enter image description here As you see after the sequence of 17, 18, 19 there is also hex values but my program prints ffffffff repeatedly.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
Davide
  • 1,931
  • 2
  • 19
  • 39

3 Answers3

5

You opened the file in a text mode, and not as binary. Different platforms may behave differently.

In this case, Microsoft Windows decided that this plain text file ends at the first occurrence of Ctrl+Z (0x1A), and returns EOF for all fgetc afterwards.

Explicitly state that you want to open the file as binary:

fp = fopen ("yourfile", "rb");

and the problem goes away.

Jongware
  • 22,200
  • 8
  • 54
  • 100
1

I think your loop should look like this:

int ch;
while (!feof(fp)) {
    ch = fgetc(fp);
    printf("%x ", ch);
}

It's completely unclear to me why you are using st.st_size here.

Wolf
  • 9,679
  • 7
  • 62
  • 108
  • If I use with while cycle it prints until 0x19 but the file is longer and longer – Davide Jan 26 '17 at 14:58
  • Well, your problem was obviously [using text mode](http://stackoverflow.com/a/41876316/2932052). But what's the reason behind not using `foef`: performance? – Wolf Jan 26 '17 at 15:20
  • Yes. I used st.st_size to show you wrongs hex. Yes, now I'm already using EOF – Davide Jan 26 '17 at 15:22
1

On Windows, the character 0x1A (Ctrl+Z) is the EOF character for text mode; see this question.

If you're reading from a binary file like a JPEG, you should do so with first opening the file as binary (fopen mode "rb"), then fread into a pre-allocated buffer, the size of which you would determine with ftell with the file pointer at the end of the file:

size_t i, len;
char *buffer = NULL;
fp = fopen(argv[1], "rb");
if(!fp)
   // handle error

fseek(fp, 0, SEEK_END);
len = ftell(fp);
rewind(fp);

buffer = malloc(len + 1);
if(!buffer)
    // handle error

fread(buffer, 1, len, fp);
for(i = 0; i < len; i++)
{
    printf("%.2X ", buffer[i]);
}

free(buffer);
buffer = NULL;
Community
  • 1
  • 1
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85