【发布时间】:2017-09-22 13:33:11
【问题描述】:
我使用 c 编程来获取存储卡上删除的 jpeg 数据(由文件 card.raw 表示)。我现在正在尝试恢复这些 jpeg 文件。 问题:我的代码编译但它不会终止。 我想到了while循环的另一个条件,但不幸的是我不知道如何正确地做。 (试过EOF和feof)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
fprintf(stderr, "Usage: ./recover filename\n");
return 1;
}
// open input file
FILE *inptr = fopen(argv[1], "r");
//error if unable to open
if (inptr == NULL)
{
fprintf(stderr, "Could not open %s.\n", argv[1]);
return 2;
}
//variables
char buffer[512] = {0};
char jpeg1[4] = {0xff, 0xd8, 0xff, 0xe0};
char jpeg2[4] = {0xff, 0xd8, 0xff, 0xe1};
int count = 0;
char name[8] = {0};
FILE *outfile;
int isopen = 0;
//do while end of file is not reached
while (fread(buffer,1, 512, inptr) > 0)
{
//compare buffer to bytes
if (memcmp(buffer, jpeg1,4) == 0 || memcmp(buffer, jpeg2,4) == 0)
{
//close old outfile if open
if(isopen ==1)
{
fclose(outfile);
}
//name for next outfile
count ++;
sprintf(name, "%03d.jpg", count);
//open outfile and catch errors
outfile = fopen(name, "w");
if (outfile == NULL)
{
printf("Error opening outfile.\n");
return 3;
}
isopen = 1;
// write the first 512 bytes
fwrite(buffer, 1, 512, outfile);
}
//no new jpeg
// if outfile is open
if (isopen == 1)
{
fwrite(buffer, 1, 512, outfile);
}
//move reader of fread()
fseek(inptr, 1, SEEK_SET);
}
//close files
fclose(inptr);
fclose(outfile);
// success
return 0;
}
【问题讨论】:
-
你应该使用
fread(...) > 0而不是fread(...) == 512 -
尽量避免在您的代码中使用幻数(例如
512)。如果您在代码顶部使用#define NMEMB 512,它必须更容易(并且更容易维护)。如果您需要更改值,您可以在一个地方进行更改,而不必在代码中的每个fread/fwrite调用中进行选择以更改它:)当有人查看 @ 时也不足为奇987654329@,例如size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); -
这是 CS50 课程的问题之一。阅读How to Ask,特别是关于作业问题的部分。
-
注意:使用
fread(),最好以binary模式打开文件fopen(argv[1], "rb"); -
提示:避免小气使用缓冲区。
char name[8] = {0}; ... sprintf(name, "%03d.jpg", count);这是一个缓冲区溢出,count超出范围 [-99...999]。为更广泛的计数做好准备。也许char name[21 /*64-bit int */ + 4 /* fmt */ + 1] = {0};。根据设计,您“知道”代码永远不需要超过 8 大小的缓冲区,但现在代码已经损坏,所以可能是一个大的count使问题更加复杂。