CS5Ox Pset4 Recover:代码仅恢复部分图像
CS5Ox Pset4 Recover: code only recovers partial images
我有一些 CS50 Pset4 的半工作代码。如果你 运行 它你会看到它恢复了 27 个 jpg 文件,但只有前几行是可见的。
有人能指出我正确的方向吗?
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef uint8_t BYTE;
int main (int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
fprintf(stderr, "Usage: ./recover infile\n");
return 1;
}
// open file to be recovered
FILE *infile = fopen(argv[1], "r");
if (infile == NULL)
{
fprintf(stderr, "Could not open infile.\n");
return 2;
}
// temp storage for blocks
BYTE buffer[512];
// variable to store filename
char filename[8];
//store number of recovered files
int n = 0;
// temp storage for outfiles
FILE* outfile = NULL;
// iterate over all blocks of memory until end of SD card is reached
while (fread(buffer, 512, 1, infile) != 0)
{
// read one block
fread(buffer, 512, 1, infile);
// check if block is start of jpeg
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
//close previous file if already open
if(outfile != NULL)
{
fclose(outfile);
}
// creeate new outfile
sprintf(filename, "%03i.jpg", n);
outfile = fopen(filename, "w");
// write block to outfile
fwrite(buffer, 512, 1, outfile);
n++;
}
else
{
// write block to current outfile
if(outfile != NULL)
{
fwrite(buffer, 512, 1, outfile);
}
}
}
//close last outfile
fclose(outfile);
//close infile
fclose(infile);
}
我发现有几件事可能会导致该问题。
首先,检查您的 n
计数器的顺序。应该在您实际开始写入新文件之前添加计数器,但这只是一个偏好问题,以及您希望代码有多干净。
其次,尝试用以下代码替换您的 else
条件:
if(outfile != NULL)
{
fwrite(buffer, 512, 1, outfile);
}
注意:请记住,我已将您的 else
条件替换为 if
条件。这是因为当满足第一个if
条件时,然后执行这个条件和'jumps out of the block'。所以 else
将只执行第一个 if
条件不会执行。
如果您想保留 else
条件,那么您应该嵌套另一个 if
,就像您在代码中所做的那样。
将 else
替换为 if
,无论 jpg 的前 3 个字节的值如何(即,无论它们是 0x00、0xff、 0x00),你会得到一个非常清晰易懂的代码。
最后,也是更重要的一点:为什么要在同一个操作中对同一个文件写入两次?注意 n++
计数器下方的 fwrite()
函数。真的有必要吗?
换句话说:删除这一行:
// read one block
fread(buffer, 512, 1, infile);
另一个错误是,你正在读取你的文件两次,并且在每一步中前进两次,所以你会得到一半的信息。
这就是您获得一半图像(大约 27 张)的原因。
删除这两行:
// read one block
fread(buffer, 512, 1, infile);
正如我所说,通过在文件中读写两次,您可以获得一半的信息。这会导致模糊的方式,在这种方式中,您将所有图像都用毫无意义的颜色(我猜)和一半的图像文件着色。
我已经 运行 check50 2016.recover recover.c
使用了您的代码和我刚刚提供给您的固定解决方案,它通过了 CS50 的 check50 的所有检查。花点时间考虑程序中的所有内容,包括控制流(它是其中的重要部分)以及指针的使用。
在没有任何经验的情况下启动 CS50 可能会让人望而生畏。保持。您已经快进入第 5 周了。
我有一些 CS50 Pset4 的半工作代码。如果你 运行 它你会看到它恢复了 27 个 jpg 文件,但只有前几行是可见的。
有人能指出我正确的方向吗?
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef uint8_t BYTE;
int main (int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
fprintf(stderr, "Usage: ./recover infile\n");
return 1;
}
// open file to be recovered
FILE *infile = fopen(argv[1], "r");
if (infile == NULL)
{
fprintf(stderr, "Could not open infile.\n");
return 2;
}
// temp storage for blocks
BYTE buffer[512];
// variable to store filename
char filename[8];
//store number of recovered files
int n = 0;
// temp storage for outfiles
FILE* outfile = NULL;
// iterate over all blocks of memory until end of SD card is reached
while (fread(buffer, 512, 1, infile) != 0)
{
// read one block
fread(buffer, 512, 1, infile);
// check if block is start of jpeg
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
//close previous file if already open
if(outfile != NULL)
{
fclose(outfile);
}
// creeate new outfile
sprintf(filename, "%03i.jpg", n);
outfile = fopen(filename, "w");
// write block to outfile
fwrite(buffer, 512, 1, outfile);
n++;
}
else
{
// write block to current outfile
if(outfile != NULL)
{
fwrite(buffer, 512, 1, outfile);
}
}
}
//close last outfile
fclose(outfile);
//close infile
fclose(infile);
}
我发现有几件事可能会导致该问题。
首先,检查您的 n
计数器的顺序。应该在您实际开始写入新文件之前添加计数器,但这只是一个偏好问题,以及您希望代码有多干净。
其次,尝试用以下代码替换您的 else
条件:
if(outfile != NULL)
{
fwrite(buffer, 512, 1, outfile);
}
注意:请记住,我已将您的 else
条件替换为 if
条件。这是因为当满足第一个if
条件时,然后执行这个条件和'jumps out of the block'。所以 else
将只执行第一个 if
条件不会执行。
如果您想保留 else
条件,那么您应该嵌套另一个 if
,就像您在代码中所做的那样。
将 else
替换为 if
,无论 jpg 的前 3 个字节的值如何(即,无论它们是 0x00、0xff、 0x00),你会得到一个非常清晰易懂的代码。
最后,也是更重要的一点:为什么要在同一个操作中对同一个文件写入两次?注意 n++
计数器下方的 fwrite()
函数。真的有必要吗?
换句话说:删除这一行:
// read one block
fread(buffer, 512, 1, infile);
另一个错误是,你正在读取你的文件两次,并且在每一步中前进两次,所以你会得到一半的信息。 这就是您获得一半图像(大约 27 张)的原因。
删除这两行:
// read one block
fread(buffer, 512, 1, infile);
正如我所说,通过在文件中读写两次,您可以获得一半的信息。这会导致模糊的方式,在这种方式中,您将所有图像都用毫无意义的颜色(我猜)和一半的图像文件着色。
我已经 运行 check50 2016.recover recover.c
使用了您的代码和我刚刚提供给您的固定解决方案,它通过了 CS50 的 check50 的所有检查。花点时间考虑程序中的所有内容,包括控制流(它是其中的重要部分)以及指针的使用。
在没有任何经验的情况下启动 CS50 可能会让人望而生畏。保持。您已经快进入第 5 周了。