【问题标题】:CS50 Recovering jpg images from card.rawCS50 从 card.raw 中恢复 jpg 图像
【发布时间】:2018-07-22 05:29:22
【问题描述】:

我有一些关于 CS50 Pset4 恢复 jpg 文件的问题。

我的代码能够编译,但是只创建了 2 个 jpg 文件,即使它应该创建了 50 个 jpg 文件。我没有看到代码有任何问题,但我怀疑 jpg 文件没有被创建,因为不知何故 fread 函数比它应该更早地到达 EOF。

但我对此一无所知。任何帮助识别错误将不胜感激:D

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

int main (int argc, char * argv[])
{
//Only accepts 2 arguments
if (argc != 2)
{
    fprintf(stderr, "Usage: Recover JPEG images\n");
    return 1;
}

//opens file file for reading
FILE *file = fopen(argv[1], "r");
if (file == NULL)
{
    fprintf(stderr, "Unable to open file\n");
    return 2;
}

unsigned char buffer[512];

//initializing file numbering
int count = 0;
char filename[7];
FILE *img = NULL;

//reads 512 bytes each time until EOF
while(fread(buffer, 512, 1, file) == 1)
{
    //Detect the start of a JPEG file
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
    {
        //if output file was not created before, create one
        if (img == NULL)
        {
            sprintf(filename, "%03i.jpg", count);
            img = fopen(filename, "w");

            if (img == NULL)
            {
                fprintf(stderr, "Unable to open %s\n", filename);
            }

            fwrite(buffer, 512, 1, img);
            count += 1;
        }
        //if output file was already created, close it and open a following output file
        else
        {
            fclose(img);

            sprintf(filename, "%03i.jpg", count);
            img = fopen(filename, "w");

            if (img == NULL)
            {
                fprintf(stderr, "Unable to open %s\n", filename);
            }

            fwrite(buffer, 512, 1, img);
            count += 1;
        }
    }
    //if there is an output file open but has not reached the start of a new jpg, write into the current opened file
    else
    {
         if (img != NULL)
         {
             fwrite(buffer, 512, 1, img);
         }
    }
}
//close all files
if (img)
{
    fclose(img);
}
fclose(file);

【问题讨论】:

  • 您的代码每隔 512 个字节就跳过一次,因为它调用了两次 fread,并且只使用了第二个。
  • 还有:"rb", "wb"
  • ...并且无法读取文件末尾的任何“%512”字节。
  • @immibis 感谢有关双重fread 的建议!我已经删除了那部分。另外@Antti Haapala 我已将代码更改为rbwb。可悲的是,我仍然无法打开任何 jpg 文件。
  • 也许您应该尝试打印缓冲区以进行调试,您确定文件已打开吗?您的代码似乎是正确的,所以问题可能出在文件读取中......

标签: c image jpeg cs50 recovery


【解决方案1】:

fread 使文件指针前进:

while(fread(buffer, 512, 1, file) == 512)
{
    fread(buffer, 512, 1, file);

此执行实际读取 1024 字节,但缓冲区仅保存后半部分(512 字节),这意味着您将跳过每个循环 512 字节

--------------------------
|512b|512b|512b|512b|512b|
--------------------------
-skip-read-skip-read-skip-

这是故意的吗?

【讨论】:

  • 感谢您指出这一点!这不是故意的,我已经更改了代码。但是我仍然无法打开任何 jpg 文件...
【解决方案2】:

好的,我终于找到了问题所在。问题是我分配了char filename[7];,在那里我给出了数字7,因为每个文件的名称都是00x.jpg,我相信它使用7个字符。但是,该程序似乎只有在我输入高于 7 的数字时才能工作,例如“8”或“10”。我相信这个额外的字符空间是用于我未能解释的 '\0' 的。如果我错了纠正我。感谢所有帮助过的人:D

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    相关资源
    最近更新 更多