CS50恢复不会输出任何图像

时间:2020-08-18 12:33:52

标签: c cs50

我正在研究CS50课程的恢复程序。以下是说明:

  • 在名为restore的目录中的restore.c文件中实现程序。

  • 您的程序应仅接受一个命令行参数,即用于从中恢复JPEG的取证图像的名称。

  • 如果没有使用一个命令行参数来执行您的程序,它应该提醒用户正确的用法,main应该 返回1。

  • 如果无法打开取证图像以供阅读,则程序应告知用户更多信息,并且main应返回1。

  • 您的程序(如果使用malloc)一定不能泄漏任何内存。

我认为我的代码应该可以工作,但是不能。实际上,它根本不输出任何图像!这是代码:

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

int main(int argc, char *argv[])
{
    FILE * pFile = NULL;
    unsigned char *buffer = malloc(512);
    char* filename = NULL;
    int filenumber = 0;

    //If user didn't print 2 items
    if(argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }

    //Open the file
    pFile = fopen(argv[1], "r");
    if (!pFile)
    {
        fprintf(stderr, "File cannot be opened\n");
        return 2;
    }

    int j=0;
    
    // checking the card by 512b chunks 
    //loop (i=0,  i++);
    while (pFile)
    {
        int i =0;
        i++;

        //k=fread (buffer, 512, i, *file);
        int k = fread(buffer, 512, i, pFile);
        
        // if 512 byte block is jpeg, make new jpeg file
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            // if it's not the first file, we should close the last one
            if (filename != NULL)
            {
                fclose(pFile);
            }

            //sprintf
            sprintf(filename, "%03i.jpg", 2);

            //FILE = fopen (W) 
            pFile = fopen(filename, "w");

            // fwrite (buffer, 512, j, *file1)
            fwrite (buffer, 512, j, pFile);

            //j=j+1
            j = j + 1;
        }

        // if k<512 - end of the loop
        if (k < 512)
        {
            return 0;
        }
    }
    free(buffer);
}

我听不懂,但是我的文件中没有弹出新文件或JPEG。当我尝试双击名为card.raw的文件时,它不允许我打开它。

1 个答案:

答案 0 :(得分:2)

您有很多问题。在调试器中运行您的代码应在一秒钟之内即可显示出大部分代码。

让我们看看:

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

int main(int argc, char *argv[])
{
    FILE * pFile = NULL;
    unsigned char *buffer = malloc(512);
    char* filename = NULL;  <<==== You never allocate any memory for this. Use an array.
    int filenumber = 0;

    //If user didn't print 2 items
    if(argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }

    //Open the file
    pFile = fopen(argv[1], "r");
    if (!pFile)
    {
        fprintf(stderr, "File cannot be opened\n");
        return 2;
    }

    int j=0;
    
    // checking the card by 512b chunks 
    //loop (i=0,  i++);   <<== No information provided by this comment.
    while (pFile)       <<== pFile is your input file. This should never change. ???
    {
        int i =0;
        i++;

        //k=fread (buffer, 512, i, *file);    <<== Useless comment. Nearly same as code below but causes compiler error
        int k = fread(buffer, 512, i, pFile); <<== i is always 1 and must be 1. Don't use variable.
                                              <<== BTW: You should check k **before** using the buffer.


        // if 512 byte block is jpeg, make new jpeg file
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            // if it's not the first file, we should close the last one
            if (filename != NULL)
            {
                fclose(pFile);  <<== Yikes!!! This is your input file.
            }

            //sprintf  <<== Yes, that's obvious. Useless comment.
            sprintf(filename, "%03i.jpg", 2);  <<== Yikes!! You never allocate memory. NULL pointer!!
                                               <<== Why do you always print 2? you have a counter.

            //FILE = fopen (W)  <<== Again no useful information in comment
            pFile = fopen(filename, "w");  <<== Feed NULL into fopen and kill pFile.

            // fwrite (buffer, 512, j, *file1)  <<== you know what I mean...
            fwrite (buffer, 512, j, pFile);  <<== You only have 1 buffer, why write j blocks?

            //j=j+1  <<== obvious
            j = j + 1;
        }

        // if k<512 - end of the loop
        if (k < 512)   <<== fread returns number of elements, i.e. 1, not number of bytes.
        {
            << you return without
               - closing files
               - freeing buffer
            return 0;
        }
   <<== Now you go back to top of the loop and want to read next block from your raw file but pFile was killed in the loop.

    }
    free(buffer);
}