C程序没有终止

C程序没有终止,c,jpeg,restore,cs50,C,Jpeg,Restore,Cs50,我使用c编程来获取存储卡(由文件card.raw表示)上删除的jpeg数据。我现在正在尝试还原这些jpeg文件。 问题是:我的代码可以编译,但不会终止。 我考虑了while循环的另一个条件,但不幸的是,我不知道如何正确执行。(试用EOF和feof) #包括 #包括 #包括 int main(int argc,char*argv[]) { //确保正确使用 如果(argc!=2) { fprintf(stderr,“用法:./recover filename\n”); 返回1; } //打开输入文

我使用c编程来获取存储卡(由文件card.raw表示)上删除的jpeg数据。我现在正在尝试还原这些jpeg文件。 问题是:我的代码可以编译,但不会终止。 我考虑了while循环的另一个条件,但不幸的是,我不知道如何正确执行。(试用EOF和feof)

#包括
#包括
#包括
int main(int argc,char*argv[])
{
//确保正确使用
如果(argc!=2)
{
fprintf(stderr,“用法:./recover filename\n”);
返回1;
}
//打开输入文件
文件*inptr=fopen(argv[1],“r”);
//无法打开时出错
如果(inptr==NULL)
{
fprintf(stderr,“无法打开%s。\n”,argv[1]);
返回2;
}
//变数
字符缓冲区[512]={0};
char jpeg1[4]={0xff,0xd8,0xff,0xe0};
char jpeg2[4]={0xff,0xd8,0xff,0xe1};
整数计数=0;
字符名[8]={0};
文件*输出文件;
int-isopen=0;
//在未到达文件结尾时执行此操作
而(fread(缓冲区,1512,inptr)>0)
{
//将缓冲区与字节进行比较
如果(memcmp(缓冲区,jpeg1,4)==0 | | memcmp(缓冲区,jpeg2,4)==0)
{
//如果打开,关闭旧的输出文件
如果(等参线==1)
{
fclose(输出文件);
}
//下一个输出文件的名称
计数++;
sprintf(名称为“%03d.jpg”,计数);
//打开outfile并捕获错误
outfile=fopen(名称,“w”);
if(outfile==NULL)
{
printf(“打开输出文件时出错。\n”);
返回3;
}
等参=1;
//写入前512字节
fwrite(缓冲区,1512,输出文件);
}
//没有新的jpeg
//如果输出文件是打开的
如果(等参线==1)
{
fwrite(缓冲区,1512,输出文件);
}
//移动fread()的读卡器
fseek(inptr,1,SEEK_SET);
}
//关闭文件
fclose(inptr);
fclose(输出文件);
//成功
返回0;
}
您可以无限期地循环

除去

fseek(inptr, 1, SEEK_SET);
这将在每次执行循环时重置指向文件开头的文件指针



注:尽量避免使用像512这样的神奇数字。我会使用像这样的定义来代替。

而不是
fread(…)>0
你应该使用
fread(…)==512
尝试避免在代码中使用幻数(例如
512
)。如果您在代码顶部定义NMEMB 512,那么它必须更容易(也更容易维护)。如果您需要更改值,您只需在一个地方进行更改,而不必通过每次调用代码来更改值。:)当有人看到
man-fread
,例如
size\t-fread(void*ptr,size\t-size,size\t-nmb,FILE*stream),这也就不足为奇了这是CS50课程问题之一。阅读,特别是关于家庭作业问题的部分。注意:使用
fread()
,最好以二进制模式
fopen(argv[1],“rb”)打开文件提示:避免对缓冲区吝啬<代码>字符名[8]={0}。。。sprintf(名称为“%03d.jpg”,计数)这是一个缓冲区溢出,
计数
超出范围[-99…999]。为更广泛的情况做好准备。可能
字符名[21/*64位int*/+4/*fmt*/+1]={0}。通过设计,您“知道”代码永远不需要超过8个大小的缓冲区,但现在代码已中断,因此可能是大量的
计数使问题更加复杂。问题当然只是
fseek
将读取指针重置为文件开头
fread
如果没有读取完整的数据块,则返回的字节数可能少于512字节,但这仍然需要处理。
fread
的位仍处于关闭状态-如果它读取511字节,则会退出循环并错过最后读取的数据块。是的,现在看起来好多了:)
fseek(inptr, 1, SEEK_SET);