what is the meaning of

fseek(file, -4, SEEK_CUR);

Dani AI

Generated

Short answer: fseek(file, -4, SEEK_CUR) moves the stream position indicator four bytes backward from where it currently is. It’s basically “undo four bytes” (useful if you read ahead and want to inspect the bytes you just read). fseek returns 0 on success and non‑zero on error (for example if the result would be before the start of the file or the stream is not seekable). Use ftell() to print the current offset while debugging.

Why your program hung: the code calls fgetc() repeatedly inside the if expression, and each fgetc() advances the file pointer. That makes the tests consume bytes unexpectedly and misalign subsequent reads. Also createFile() uses while (1) with no safe exit — if no next JPEG signature is ever found, it will loop forever. As suggested, consider operating on fixed 512‑byte blocks instead of repeatedly peeking single bytes; that both preserves block alignment and avoids fiddly fseek gymnastics. Also open files in binary mode ("rb"/"wb"), check return values of fopen, fread, fwrite, and fseek, and don’t use while (!feof(...)).

A simple, robust pattern (read one 512‑byte block at a time, check its first 4 bytes for a JPEG header, start/stop output files accordingly):

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

int main(void) {
    FILE *in = fopen("card.raw", "rb");
    if (!in) return 1;
    unsigned char buf[512];
    FILE *out = NULL;
    int img = 0;
    while (1) {
        size_t n = fread(buf, 1, 512, in);
        if (n == 0) break;
        if (n >= 4 && buf[0]==0xff && buf[1]==0xd8 && buf[2]==0xff && (buf[3] & 0xf0) == 0xe0) {
            if (out) fclose(out);
            char name[16];
            sprintf(name, "%03d.jpg", img++);
            out = fopen(name, "wb");
            if (!out) { fclose(in); return 2; }
        }
        if (out) fwrite(buf, 1, n, out);
        if (n < 512) break;
    }
    if (out) fclose(out);
    fclose(in);
    return 0;
}

Quick debugging tips: print ftell() values to watch how your pointer moves, hexdump card.raw to confirm signatures, and avoid while(!feof(...)). That approach will prevent the infinite loop you saw and is the usual solution for the “recover JPEGs from a raw image” style problem (as discovered after testing every 512‑byte block).

Recommended Answers

All 4 Replies

It moves the file pointer 4 bytes towards the beginning of the file from the current position.

can you explain why this code always enter an infinte loop card.raw is a file containg jpg pic that i an trying to recover.

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

int createFile(FILE* file, FILE* outfile);
int createName(void);

int main (void)
{

    FILE* cardp = fopen("card.raw", "r");
    FILE* outp = fopen("1.jpg", "w");

    while (!feof(cardp))
    {
        if (((fgetc(cardp) == 0xff) && (fgetc(cardp) == 0xd8) && (fgetc(cardp) == 0xff) && (fgetc(cardp) == 0xe0)) || ((fgetc(cardp) == 0xff) && (fgetc(cardp) == 0xd8) && (fgetc(cardp) == 0xff) && (fgetc(cardp) == 0xe1)))
        {
            printf("here");

            createFile(cardp, outp);
        }
    }   
    return 0;
}

int createName(void)
{

    return 0;
}

int createFile(FILE* file, FILE* outfile)
{

    //while not at the bening of another file do:
    while (1)
    {
        char block[512];
        fseek(file, -4, SEEK_CUR);
        fread(&block, 512, 1, file);

        //write 512 block
        fwrite(&block,512, 1, outfile);

        if (((fgetc(file) == 0xff) && (fgetc(file) == 0xd8) && (fgetc(file) == 0xff) && (fgetc(file) == 0xe0)) || ((fgetc(file) == 0xff) && (fgetc(file) == 0xd8) && (fgetc(file) == 0xff) && (fgetc(file) == 0xe1)))
            break;


    }

    return 0;
}

Did you use your compiler's debugger so that you can see exactly what is happening? I can't answer your question without having a copy of card.raw and debugging your program.

If it reads 512 bytes, then backs up 4 bytes, what makes you think that the next 8 bytes will be the same as what that if statement expects? Is the size of the file evenly divisible by 512?

thanks dragon. you helped me. i should have check every 512 bytes i read to see if it is off the patten not only 4 thanks a lot

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.