我正在努力恢复哈佛大学的cs50x并且因为开放不断返回NULL而被卡住了。
// Read each 512 bytes until end of file is reached
FILE* img = NULL;
while (fread(&data, 512, 1, diskptr) == 1)
{
// Check for jpeg start
if (checkStart(data, jStart, jStartOE) == true)
{
jFound++;
if (jFound == 1)
{
printf("newfound\n");
// Name and open the first jpeg file
char title[12];
sprintf(title, "%03d.jpg", jFound - 1);
FILE* img = fopen(title, "w");
fwrite(&data, 512, 1, img);
}
else if (img != NULL)
{
printf("closed\n");
// Close old file
fclose(img);
// Open new file
char title[12];
sprintf(title, "%03d.jpg", jFound - 1);
FILE* img = fopen(title, "w");
fwrite(&data, 512, 1, img);
}
}
else if (jFound > 0 && img != NULL)
{
printf("written\n");
fwrite(&data, 512, 1, img);
}
}
我添加了那些printfs以查看是否曾经执行了其他块,当我运行它时,新的打印一次,然后没有其他打印。由于某种原因,open返回NULL,其他代码块永远不会被执行。
对于某些情况: 该程序的目的是从.raw文件中恢复已删除的jpeg。 checkStart只是一个简单的函数,它确定512字节块的前四个字节是否包含jpeg签名值。如果他们这样做,则返回true表示当前块是新jpeg的开始,如果它们不是,则返回false。 jFound只是一个变量,我用它来跟踪程序找到了多少jpeg,因此它可以正确命名它们并在已经找到第一个jpeg时写入。
答案 0 :(得分:8)
这一行:
FILE* img = fopen(title, "w");
声明变量' img'在以
开头的代码块范围内if( iFound == 1 ) and if( img != NULL )
变量' img'在每个代码块中是不同的。
这些声明会掩盖发布代码顶部的声明。
建议
img = fopen(title, "w");
(因此不会声明新的' img'变量)
在发布的代码中的两个位置会出现此问题。
我还为fopen()
的调用添加了一些错误检查我还删除了逻辑中的卷积
但是,当任何其他文件也位于磁盘的同一区域时,代码将不会始终捕获实际.jpg文件的末尾。
如果任何文件段被覆盖,代码将无法捕获这一事实。
即。代码可能无法正确提取.jpg文件,并且写入提取的文件副本可能会导致覆盖要提取的已删除文件的部分。 I.E.将新文件放在不同的磁盘上
FILE* img = NULL;
while (fread(&data, 512, 1, diskptr) == 1)
{
// Check for jpeg start
if (checkStart(data, jStart, jStartOE))
{
if (img != NULL)
{
printf("closed\n");
// Close old file
fclose(img);
}
// Open new file
char title[12];
sprintf(title, "%03d.jpg", jFound - 1);
if( NULL == (img = fopen(title, "w") ) )
{ // then fopen failed
perror( "fopen for output file failed");
exit( EXIT_FAILURE );
}
// implied else, fopen successful
fwrite(&data, 512, 1, img);
}
else if (img != NULL)
{
printf("written\n");
fwrite(&data, 512, 1, img);
}
}