0

I'm recovering the files just fine, but my program seems stuck in the while loop. I've tried adding extra closing statements and adding else statements, but I can't seem to find where/why it won't end.

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

int main(int argc, char *argv[])
{
    if(argc != 2) {
        fprintf(stderr, "Invalid number of arguemnts\n");
        return 1;
    }

    // Open memory card
    FILE *f = fopen(argv[1], "r");
    if(f == NULL) {
        fprintf(stderr, "Could not open source file\n");
        return 2;
    }

    // Initialize variables
    unsigned char buffer[512];
    int imageCounter = 0;
    char filename[8];
    FILE *img = NULL;


    // Iterate over card
    while (fread(buffer, 512, 1, f) == 1) {
        // Check if buffer chunk is start of JPEG
        if( buffer[0] == 0xff &&
            buffer [1] == 0xd8 &&
            buffer[2] == 0xff &&
            (buffer[3] & 0xf0) == 0xe0) {
            //You have the start of a JPEG

                // If not first JPEG, close previous before opening new
                if(imageCounter > 0) { fclose(img); }

                // Create file with proper filename & open for writing
                sprintf(filename, "%03i.jpg", imageCounter);
                imageCounter ++;
                img = fopen(filename, "w");

                // Error check
                if (img == NULL) {
                    fprintf(stderr, "Could not open file %s to write\n", filename);
                    return 3;
                }

                fwrite(buffer, 512, 1, img);
            }

            if (imageCounter > 0) {
                    // If buffer[byte] is not the start, continue writing
                    img = fopen(filename, "a");

                    // Error check
                    if (img == NULL) {
                        fprintf(stderr, "Could not open file %s to write\n", filename);
                        return 4;
                    }

                    fwrite(buffer, 512, 1, img);
                    fclose(img);
            }
        }

    fclose(img);
    fclose(f);
    return 0;
}
2

This is another case where files are being opened too many times concurrently. Each file is being opened in the signature check code block in "w" mode. Later, it's being reopened again in "a" mode without being closed in between. This is wreaking havoc at the end of the program during the exit routines that execute when a program is closing. It's there that it is hanging.

Here's the thing. The output program only needs to be opened one time and only needs to be closed one time. Once a file is opened for write, additional fwrite calls will simply write more data at the end of the file (or at the current pointer position if you manually move it). You definitely do NOT need to open it for append to do an additional write! In fact, you shouldn't. (Similar logic applies to opening a file for read.)

So, try rewriting your code a bit, using only one fopen and one fclose for output files, along with only one fopen and fclose for the input file.

BTW, as a side note, how many times does the first block with the signature get written out to the output file? ;-)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

2
  • Ah yes, that BTW was totally my hangup. So conceptually, because the read and write streams are open on the stack and we're dealing with contiguous 512B chunks, there's no need to open and close the stream between them? – lurch101 Apr 16 '20 at 13:54
  • Almost correct. Once the read and write streams are right, there's no need to reopen the streams unless they are closed. The size of the read/writes don't matter at all. Reads and writes will be contiguous unless the code moves the file pointer using an fseek call. – Cliff B Apr 16 '20 at 15:58

You must log in to answer this question.

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