0

card.raw is in the same folder as my recover program. When I try to execute it, my program spits back to me "file could not be opened" which is what I programmed it to do if the file pointer returns NULL.

I also tried directly inputing "card.raw" into the program and switching from int main (int argc, char* argv[]) to just int main(void) but the same thing happens.

What have I messed up?

edit: I added perror() under if (inptr==NULL) and when I run the program it gives back "Success" but then also "file could not be opened". What does this mean?

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


int main (void)
{

    // open the file to be read for recovery
    FILE* inptr = fopen("card.raw", "r");
    if (inptr==NULL);
    {   
        perror("Error:");
        printf("file could not be opened\n");
        return 1;
    }

    // measure size in bytes of infile
    long long S = sizeof("card.raw");

    // initialize file state as closed (has not yet been opened)
    char state = 'C';

    // initialize file pointer
    FILE* image;

    // iterate through file, identifying jpeg images
    int x;
    for (x=0; x<(S/512); x++)
    {
        // at the start of each block...
        fseek(inptr, x*(512), SEEK_SET);

        // ...scope the first four bytes
        int buffer[512];
        fread(buffer, 512, 1, inptr);

        // return to start of block
        fseek(inptr, x*512, SEEK_SET);

        // pull up what jpeg header bytes should be...
        int jcheck1[4] = {0xff, 0xd8, 0xff, 0xe0};
        int jcheck2[4] = {0xff, 0xd8, 0xff, 0xe1};

        // compare the first four bytes of block to jpeg header bytes
        int match = 0;
        if (memcmp(buffer, jcheck1, 4)==0)
            match = 1;
        if (memcmp(buffer, jcheck2, 4)==0)
            match = 1;

        // if first four bytes are a match...
        if (match == 1)
        {   
            // if jpeg is already open, close it
            if (state == 'O')
            {
                fclose(image);
            }

            // create a title
            char T[8];      
            if (x<10);
            {
                sprintf(T, "00%d", x);
            }
            if (x<100); 
            {
                sprintf(T, "0%d", x);
            }
            if (x>100)
            {
                sprintf(T, "%d", x);
            }

            // open new image file
            image = fopen(T, "w");
            S = 'O';

            // write contents of this block in new image    
            fwrite(inptr, 512, 1, image);

            // leave this file open and repeat loop...  
        }

        // if not a match...
        else
        {
            // then if a file is already open...
            if (S = 'O')
            {
                // write this block on the same image
                fwrite(inptr, 512, 1, image);
            }
        }
    }

    // close FILE - prevent memory leak
    fclose(inptr);

    // close the program
    printf("Your images have been recovered.\n");
    return 0;
}

1 Answer 1

2

You could try printing out the filename before trying to open the file to confirm that it's correct. You should also hardcode the filename into the program, as specified by the pset and get rid of the argc test completely. It was a nice idea, but it won't pass check50 as it is currently written.

// open input file
FILE* inptr = fopen("card.raw", "r");

BTW, you are using card.raw and not something else like card.jpg, right?

[EDIT: second answer after comment and another review.]

Well, I've been too focused on getting my own environment working again today that I couldn't actually test anything. I was also really distracted. Having said that, I found the issue.

if (inptr==NULL);
{

You see that semicolon? It basically tells your code "If (inptr == NULL) do nothing." It also separates the IF statement from the code block in the curly braces that follow. The result is that the code block gets executed every time. Since it is an error message and a return statement, the program terminates.

You've made this error in several places, so you need to go back and review your code. Any if(...) statements followed by a semicolon needs to have the semicolon removed. I think I saw one or two other issues that I'm surprised got past the compiler. Did you turn the warnings=errors flag off when you compile?

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

2
  • I've also tried hardcoding in and skipping the whole command line argument idea but even with "card.raw" hardcoded into fopen it doesn't find the file. I updated my code with card.raw hard coded in. Yeah I'm using card.raw not card.jpg or another name. So confusing
    – Noodlegasa
    Commented Nov 16, 2015 at 6:08
  • Nick: Please read Cliff's comment above. The line if (inptr == NULL); is the problem. The semicolon at the end of the line means that the whole if condition ends there and that whatever is stated afterwards (within your curly braces) will execute regardless of the condition. That is the problem.
    – Irene
    Commented Nov 16, 2015 at 20:00

You must log in to answer this question.

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