0

I've been working on recover for days now.

I've been able to solve the segmentation fault issues and the code compiles and creates all 50 jpg files, but doesn't write the files correctly. I played moving conditions around the code, however I feel a don't know what I'm actually doing.

I think my error is somewhere within the 2nd ELSE, where blocks of 512 bytes are written to files that already exist. In my case I use the jpeg counter to keep track of how many jpg files exist and target the correct file to append the data to.

Question 01:

Referring to the ELSE block in question,

By reading other student's code, I realize most of you are using fwrite(filename, "w") instead of the "a" that can be used to append information to a file the already exists.

Why ?

Question 02:

what's wrong with my code ? When I open the files within vs code, I can see just part of the image, under 15%

any input is appreciated, than you,

al.

...

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

typedef uint8_t BYTE;

int main(int argc, char * argv[])
{
    // Check usage
    if (argc != 2)  {   printf("\nUsage: ./recover IMAGE\n");
                        return 1;   }

    // the file name card.raw is treated as a string
    // hence the use of char*, we are using argv[1] from the command line

    char * filename=argv[1];

    // Open file, assign file to pointer file
    FILE * fileptr = fopen(filename, "r");


    // here I check the return value, make sure you don't get NULL
    if (fileptr==NULL)      {       printf("\ncan't open file\n");
                                    return 1;   }

    // the number of bytes in each block to read is 512 bytes
    // hereby I declare an array, elements type BYTE.

    BYTE buffer[512];


    //  this variables are just to count within certain conditions,
    //  and check if the code is doig what I want

    int     totalblocks=0;
    int     njpeg=0;
    int     noheaderblock=0;

    while(fread(buffer, 1, 512, fileptr)==512)
    {
        //total no. blocks of 512 bytes read by fread
        totalblocks++;

        FILE * fileptr2=NULL;
        FILE * fileptr3=NULL;
        char text[20];
        char text2[20];

        //  is it start of jpeg?
        if
        ( ( buffer[0]==0xff && buffer[1]==0xd8 &&
            buffer[2]==0xff) && ( (buffer[3] & 0xf0) == 0xe0 )  )

        {   njpeg++;
            // is it the first jpeg ?
            if(njpeg==1)
            {
                sprintf(text, "%03d.jpg", njpeg);
                fileptr2= fopen(text,"w");

                if(fileptr2==NULL)
                { printf("\nERROR 1, file could not be written\n"); return 1;}

                fwrite( buffer, 512, 1, fileptr2 );

                // you can use the fileptr2 for next case, no need to close it
                // fclose(fileptr2);
            }

            else
            {   // close ANY fileptr that is open
                if (fileptr2!=NULL){fclose(fileptr2);}

                sprintf(text, "%03d.jpg", njpeg);
                fileptr2= fopen(text,"w");

                if(fileptr2==NULL)
                { printf("\nERROR 2, file could not be written\n"); return 1;}

                fwrite( buffer, 512, 1, fileptr2 );


                fclose(fileptr2);
            }

        }

        else
        {   noheaderblock++;
            //printf("\ntotal no. of jpeg blocks read (inside ELSE)= %d", njpeg);

            sprintf(text, "%03d.jpg", njpeg);
            fileptr3= fopen(text,"a");

            if(fileptr3==NULL)
            { printf("\nERROR 3, file could not be written\n"); return 1;}

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

        printf("\ntotal no. of jpeg blocks read= %d", njpeg);
        printf("\nblocks with no jpeg header= %d", noheaderblock);
        printf("\ntotal no. blocks read= %d", totalblocks);
        printf("\n");



    }

}


1 Answer 1

1

Re: "w" vs. "a". This is about how a file is opened. If opened for "w" or write, if the file already exists, it will first be emptied (or deleted and recreated as an empty file). W will give you a fresh empty file when you open it. OTOH, the "a" or append mode will leave an existing file intact and any writes to the file will be appended to the existing content. That's why you want to use "w". If the file already exists, "a" would just tack more data to the end of an existing file. That means the new data doesn't get it's own file and the existing file gets corrupted.

Keep this in mind. You OPEN a file once, but you can write to it as many times as needed.

The next issue is this. Why is the code closing the output file after writing the signature block? Since the subsequent non-signature data needs to be written to the same file, just leave filepointer2 open and write them to the same file. filepointer3 is not needed.

Efficiency tip: Opening and closing a file is a very resource intensive process. It's better to leave a file open while working with it than to repeatedly open and close the same file.

I think you're right about the problem being with the second else clause. It looks like it's inside the curly braces for the code block for the signature if statement and attached to the second if statement. It should be outside of the first IF statement's curly braces. This is why it's good to properly format code. Uniform indentation would show this up easily. I recommend that you run it through style50 and reformat the code. Spend some quality time with style50 until you get to where it's happy with your formatting and you don't need it anymore. It'll pay off greatly in the future.

BTW, what's the name of the first file that you create? What's the name of the first file supposed to be? 000.jpg or 001.jpg?

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

2
  • hello Cliff, thank you so much for your explanations as always. I'm working on it. Sep 30, 2022 at 2:00
  • thank you @cliff-b I had several issues. I fixed the ones you mentioned, but there were more. After the changes I kept having segmentation problems. The issue had to do with how the second or output file pointer changes as the number of jpegs read increased. I had to add a condition to activate the second else clause. Why is this happening ? Sep 30, 2022 at 7:16

You must log in to answer this question.

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