改进C代码以删除复制粘贴

时间:2016-05-10 15:42:55

标签: c cs50

P.S。有些人在理解问题时遇到了问题,如何改进我的代码'。我真的无法让它更清晰。我在此期间解决了这个问题。

我正在完成从CD卡文件(.raw)中恢复照片的作业,首先通过他们的“魔术数字”找到它们。如果有人知道它是什么,它就是CS50课程的一部分。

无论如何,它似乎工作正常。我可以恢复所有照片,但其中一些质量较差,其他(很多白色像素) - 不确定它是否有意。

在代码中,根据条件我打开并关闭jpg文件以将信息写入其中。我无法找到一种方法来避免复制粘贴fopen,fwrite和fclose文件。我想改进这一部分。这是代码:

typedef uint8_t BYTE;

int main(void)
{
    // open input file 
    FILE* card_file = fopen("card.raw", "r");
    if (card_file == NULL)
    {
        printf("Could not open card.raw\n");
        return 1;
    }

// declare output file
FILE* image;

// array to store values we read for each 512 bytes
BYTE buffer[512];

// number of jpg files found
int jpgs = 0;

// variable used to create new files
char title[10];

// execute until the end of file is reached
while(fread(&buffer, sizeof(BYTE), 512, card_file) > 0)
{
    // find a new jpg file by its magic numbers
    if((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff))
    {
        //create a new file if it's found
        sprintf(title, "%03d.jpg", jpgs);
        jpgs++;

        //open the file and check if file is opened correctly
        image = fopen(title, "a");

        if (image == NULL)
        {
            fprintf(stderr, "Could not create %03d.jpg\n", jpgs);
            return 2;
        }

        // write into the file and close it
        fwrite(&buffer, sizeof(BYTE), 512, image);
        fclose(image);
    }
    else 
    {
        //check if a jpg file was already found before
        if(jpgs > 0)
        {
            //open the file and check if file is opened correctly
            image = fopen(title, "a");

            if (image == NULL)
            {
                fprintf(stderr, "Could not create %03d.jpg\n", jpgs);
                return 2;
            }

            // write into the file and close it
            fwrite(&buffer, sizeof(BYTE), 512, image);
            fclose(image);
        }
    }
}

//close the input file
fclose(card_file);

}

我试图创建一个单独的函数,但无法弄清楚如何处理指向我需要传递给它的整数值的指针。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

需要通过引用传递的唯一内容是titlebuffer,您需要返回一个我们可以测试的布尔值,以允许调用者的return 2;。< / p>

int appendBuffer(char *title, BYTE *buffer)
{
    //open the file and check if file is opened correctly
    FILE* image = fopen(title, "a");

    if (image == NULL)
    {
        fprintf(stderr, "Could not open %s\n", title); //note reuse of title now
        return 0; //it didn't work
    }

    // write into the file and close it
    fwrite(buffer, sizeof(BYTE), 512, image);
    fclose(image);
    return 1; //it worked
}

用法:

// find a new jpg file by its magic numbers
if((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff))
{
    //create a new file if it's found
    sprintf(title, "%03d.jpg", jpgs);
    jpgs++;

    if (!appendBuffer(title, buffer)) return 2;
}
else 
{
    //check if a jpg file was already found before
    if(jpgs > 0)
    {
       if (!appendBuffer(title, buffer)) return 2;
    }
}

比较许多连续字节的另一个想法是,使用memcmp而不是&&链:

const char magic[] = {0xff, 0xd8, 0xff};

// find a new jpg file by its magic numbers
if (memcmp(buffer, magic, 3) == 0)