4

I am trying to read a file "file.raw" and 4 bytes at a time to an array and check if it has the particular 4 byte signature I am looking for. I am having trouble with this. The value of result I get is 0, instead of 4 when using fread.

#include<stdint.h> 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef uint8_t BYTE; 

int main(void)
{
    size_t result;
    FILE *inptr = fopen("file.raw","r+");
    //Check if file can be opened.
    if (inptr == NULL)
    {
        printf("File Open Error\n");
        return -1;
    }
    long int x = 0;

    while(!feof(inptr))
    {
        // Make space for reading in to an array
        BYTE *array = (BYTE *) malloc(10);
        if(array == NULL)
        {
            printf("Array Initialization Error\n");
            return -1;
        }

        result = fread(array,1,4,inptr);
        //Exit if file not read. ** This is where I can't get past.
        if(result != 4)
        {
            printf("File Read Error\n");
            printf("%d\n",result);
            free(array);
            fclose(inptr);
            return -1;
        }

        //Compare strings

        if(memcmp(array,"0xffd8ffe0",4)==0)
        {
            printf("File Start found\n");
            printf("Exiting...\n");
            printf("%p\n",inptr);
            free(array);
            fclose(inptr);
            return 0;
        }
        x++;
        free(array);
    }

    printf("%p\n",inptr);
    printf("%ld\n",x);
    fclose(inptr);
    return 0;
}
Mat
  • 202,337
  • 40
  • 393
  • 406
kevin
  • 173
  • 3
  • 10
  • What does `ferror(inptr)` give you? – M.Babcock Jan 04 '12 at 20:55
  • 1
    Check `feof()` and `ferror()` to determine the cause: either EOF or a read failure. If a read failure check `errno` to obtain reason for failure. – hmjd Jan 04 '12 at 20:55
  • Also writing `while(!feof(inptr))` is completely broken. `feof` is only meaningful **after** the read operation has been done... – Evan Teran Jan 04 '12 at 23:16

2 Answers2

4

My guess is that it doesn't fail on the first iteration of the while loop, but rather keeps reading the file until you reach end of the file, at which point fread() returns 0 and your program exits.

The reason it's not finding the signature is this:

memcmp(array,"0xffd8ffe0",4)==0

That memcmp() call is almost certainly not what you want (it's looking for the sequence of ASCII characters '0', 'x', 'f' and 'f').

PS As noted by @Mat in the comments, for maximum portability you should open the file in binary mode ("r+b" instead of "r+").

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Very very likely. The lack of "b" in the open mode could be problematic on some platforms too. – Mat Jan 04 '12 at 21:00
  • @aix, You are right. Thanks. What should be used instead of memcmp to find if 0xffd8ffe0 is in my file? – kevin Jan 04 '12 at 21:04
  • 1
    @kevin: The `memcmp()` per se isn't the problem, it's the string that you give as the second argument. You probably want to create a char array along the lines of `char header[] = {0xff, 0xd8, 0xff, 0xe0}` and use that in the `memcmp()` call. – NPE Jan 04 '12 at 21:21
1

Try opening the file in binary mode ("r+b") instead of text mode ("r+"). You're probably being undone by unintentional CRLF conversions, messing up your binary data.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589