Aayush Agrawal
Aayush Agrawal

Reputation: 43

Unable to hit 0xff

I am having a small challange(Can be found at the bottom of the page, title is CSI. https://x.cs50.net/2012/psets/4/pset4.html, was too long for me to paste.) (And no, i am not trying to cheat, i already found a full code solution but i want mine to work..)

The job is to pretty much sniff out JPG files in a .raw file(file uploaded)

I am using the below shown code:

 #include <stdio.h>

 int main(void){
    FILE* fp = fopen("card.raw", "r");
    if (fp == NULL){
        printf("error!");
    }
    char foo[512];
    fread(foo,sizeof(foo),sizeof(foo[0]), fp);
    for(int j = 0; j < 20000; j++) {
        if (foo[0] == 0xff){
            printf("jackpot");
            return 0;
        }
        else {
            printf(" %d ", foo[0]);
            fread(foo,sizeof(foo),sizeof(foo[0]), fp);
        }
    }
}

Problem is, i dont know what the heck i am doing wrong. It is supposed to scream out and exit as soon as it hits a 0xff but instead it keeps going and going.. File can be found at https://mega.co.nz/#!tZcFWYIS!DmPAGT7FHLFgtW0SorWU-SE-gfJfR7MlbxdNucN1Biw if need be.

Update: Thanks for everybody's help, i finally got the jackpot. Here is the end code i ended up with.

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

typedef uint8_t BYTE;
int main(void){
    FILE* fp = fopen("card.raw", "rb");
    if (fp == NULL){
        printf("error!");
    }
    BYTE foo[512];    
    for (int j = 0;fread(foo,sizeof(foo),sizeof(foo[0]), fp) > 0; j++){
        if (foo[0] == 0xff){
            printf("jackpot, %d", j);
            return 0;
        }
    }
}

Upvotes: 3

Views: 235

Answers (2)

Some programmer dude
Some programmer dude

Reputation: 409422

You have two problems that I see.

One is that you don't really check anything but the first byte of the blocks you read. The second is that you continue to read without regard of end-of-file or errors.

You should redesign to read in a loop (while checking for errors and end-of-file), and in that loop have another loop to find the byte-sequence you're looking for.


Something like this:

for (;;)
{
    size_t nread = fread(...);
    if (nread == 0)
    {
        /* Error or end-of-file */
        break;
    }

    for (int i = 0; i < nread; i++)
    {
        /* Check for signature in `foo[i]` */
    }
}

If the signature is only found at the beginning of each 512-byte block, you don't need the second inner loop, and can simplify it considerably:

while (fread(...) > 0)
{
    /* Check for signature in `foo[0]` */
}

Upvotes: 2

nneonneo
nneonneo

Reputation: 179677

My guess is that you are reading the file in "r" mode, which may translate newlines and mess up the block synchronization.

Try reading the file in "rb" mode (binary mode).

Upvotes: 3

Related Questions