CS5Ox Pset4恢复:代码仅恢复部分映像
我有一些CS50 Pset4的半工作代码。如果您运行它,您将看到它恢复了27个jpg文件,但只有前几行是可见的 有人能给我指出正确的方向吗CS5Ox Pset4恢复:代码仅恢复部分映像,c,cs50,C,Cs50,我有一些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 !=
#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);
}
#包括
#包括
#包括
typedef uint8_t字节;
int main(int argc,char*argv[])
{
//确保正确使用
如果(argc!=2)
{
fprintf(标准,“用法:./recover infle\n”);
返回1;
}
//打开要恢复的文件
文件*infle=fopen(argv[1],“r”);
if(infle==NULL)
{
fprintf(stderr,“无法打开内嵌。\n”);
返回2;
}
//块的临时存储
字节缓冲区[512];
//用于存储文件名的变量
字符文件名[8];
//存储恢复的文件数
int n=0;
//输出文件的温度存储
FILE*outfile=NULL;
//迭代所有内存块,直到到达SD卡的末尾
while(fread(缓冲区,512,1,infle)!=0)
{
//读一块
fread(缓冲区,512,1,填充);
//检查块是否是jpeg的开始
如果(缓冲区[0]==0xff&&buffer[1]==0xd8&&buffer[2]==0xff&&buffer[3]&0xf0)==0xe0)
{
//如果已打开,请关闭上一个文件
如果(输出文件!=NULL)
{
fclose(输出文件);
}
//克里特新出口
sprintf(文件名为“%03i.jpg”,n);
outfile=fopen(文件名,“w”);
//将块写入输出文件
fwrite(缓冲区,512,1,输出文件);
n++;
}
其他的
{
//将块写入当前输出文件
如果(输出文件!=NULL)
{
fwrite(缓冲区,512,1,输出文件);
}
}
}
//关闭最后一个输出文件
fclose(输出文件);
//封闭填充
fclose(infle);
}
我发现了几个可能导致该问题的因素
首先,检查n
计数器的顺序。在您实际开始编写新文件之前,应该添加计数器,但这只是一个偏好问题,以及您希望代码有多干净
其次,尝试用以下代码替换您的else
条件:
if(outfile != NULL)
{
fwrite(buffer, 512, 1, outfile);
}
注意:请记住,我已将您的else
条件替换为if
条件。这是因为当满足第一个条件时,如果满足了条件,则执行该条件并“跳出块”。因此,如果
条件不执行,else
将只执行第一个。
如果您想保持else
状态,那么您应该像在代码中那样嵌套另一个If
通过将else
替换为if
,无论jpg的前3个字节的值是多少(也就是说,无论它们是0x00、0xff、0x00),您都会得到一个非常清晰易懂的代码
最后,也是更重要的一点:为什么要在同一个操作中向同一个文件写入两次?请注意n++
计数器下面的fwrite()
函数。真的有必要吗
换句话说:删除此行:
//读取一个块
fread(缓冲区,512,1,填充)代码>
另一个错误是,您正在读取文件两次,并且在每一步中前进两次,所以您将获得一半的信息。
这就是为什么你会得到一半的图片(27张左右)
删除这两行:
//读取一个块
fread(缓冲区,512,1,填充)代码>
正如我所说,通过在文件中读写两次,您可以获得一半的信息。这就导致了一种模糊的方式,在这种方式下,你可以让你的图像全部用无意义的颜色(我猜)和一半的图像文件着色
我已经用您的代码和我刚才提供给您的固定解决方案运行了check50 2016.recover.c
,它通过了CS50 check50的所有检查。花点时间考虑一下程序中的所有内容,包括控制流(它是程序的一个重要部分),以及指针的用法
在没有任何经验的情况下启动CS50可能会让人望而生畏。坚持下去。你已经快进入第五周了 您的文件名
太短(空终止?)。花了好几个小时在上面……嗯,有点浪费。@Eugene,根据规范,文件名应该是XXX.jpg。考虑到空终止,我想我需要8个字符来存储文件名。还是我遗漏了一些明显的东西?(我以0之前的经验开始cs50:)@Mark,您可以在此处找到我的输出示例:。我不知道输出应该是什么样子,但它应该是一幅清晰的图片。我错了,对不起。错算了角色。谢谢大家!这真的很有帮助。我没有意识到while循环条件中的fread也提升了指针。更改了我的代码并通过了检查50。到第5周!:D