0

Below is my working code but I've a question.

If change my char filename[8] to char filename[7] the counter does not increase. Instead, I'll only have 2 output files: 000.jpg and 001.jpg, where 001.jpg is actually the last photo i.e 049.jpg. the printf("%i\n",counter) will print 50 "1". Why does the size of my char/string affect the counter?

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

typedef uint8_t BYTE;

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: ./recover image\n");
        return 1;
    }

    FILE *inptr = fopen(argv[1], "r");
    FILE *outptr = NULL;
    if (inptr == NULL) //inptr corresponds to the file your program reads
    {
        fprintf(stderr, "Could not open %s.\n", argv[1]); //fprintf(stderr,""); Prints whatever is provided within the quotes, to the console.
        return 2;
    }

    BYTE block[512];
    int counter = 0;
    char filename[8]; //xxx.jpg\n need 8 space including terminating char

    while(1)
    {
        //fread(data, size, number, inptr) size_t is the return type of sizeof() which fread return. fread returns number of bytes read
        //sizeof(BYTE) is actually just 1. fread function's size is the number of bytes to read.
        size_t bytesread = fread(block, sizeof(BYTE), 512, inptr);

        if (bytesread == 0 && outptr != NULL) //if fread nothing break and currently no files open
        {
            fclose(outptr);
            fclose(inptr);
            break;
        }

        if((block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && (block[3] & 0xf0) == 0xe0) && outptr != NULL)
        {
            fclose(outptr);
            counter++;
            printf("%i\n",counter);
        }

        if((block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && (block[3] & 0xf0) == 0xe0))
        {
            sprintf(filename, "%03i.jpg", counter); //%03i means 3 integer with zero padding, sprinf saves the 2nd argument to the 1st
            outptr = fopen(filename, "w");
        }

        if (outptr != NULL)
        {
            fwrite(block, 1, bytesread, outptr);
        }

    }
    return 0;
}
2
0

Try using else-if instead of the ifs. Also, instead of putting 1 inside the while bracket, try putting &free or true.

If this helped, please click on the tick mark.

2
  • i tried it but didnt work. There's a reason why i used all ifs instead of else if. else if will cause the loop to restart which i dont want. – Timothy Teo Jun 3 '20 at 4:50
  • It doesn't restart the loop. But since you don't want else-if, put some extra variables and conditions so that your program works smoothly. – Vsjain Jun 3 '20 at 4:53
0

As you note in your comment, //xxx.jpg\n need 8 space including terminating char. When you try sprintf when you've only got 7 spaces, it's still putting that null terminating character at the end, though.

When I run your code with debug50, and evalute &filename and &counter, I get 0x7fffffffe3f5 and 0x7fffffffe3fc, respectively. So, when sprintf is writing that null terminating character, it's putting that value in the spot that's for counter, which is resetting it to zero.

What MARS posted in the comments is the same problem. However, probably because you've declared your variables in a different order, having only 7 chars is messing with a different variable in their code than in your code.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .