该程序的目标是从文件中恢复JPG。
我已经在CS50在线课程中解决这个问题大约四到五天了,但我无法弄清楚。我继续遇到细分错误,我也不知道为什么。
我尝试了debug50,发现程序尝试写入新文件时出现错误。为什么这样做我不知道。
我一直在把头撞在墙上的墙上,并且已经完全擦除并重写了多次。任何帮助将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage ./recover file.type\n");
return 1;
}
char *infile = argv[1];
FILE *inptr = fopen(infile, "rb");
if (inptr == NULL)
{
fprintf(stderr, "Could not open file designated to be recovered\n");
fclose(inptr);
return 2;
}
int counter = 0;
FILE *img;
uint8_t buffer[512];
while (fread(buffer, sizeof(*buffer), 512, inptr))
{
if (buffer[0] == 0xff &&
buffer[1] == 0xd8 &&
buffer[2] == 0xff &&
(buffer[3] & 0xf0) == 0xe0)
{
if (counter > 0)
{
fclose(img);
}
char filename[8];
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
counter++;
}
if (counter !=0)
{
fwrite(buffer, sizeof(*buffer), 512, img);
}
}
fclose(img);
fclose(inptr);
return 0;
}
答案 0 :(得分:1)
char filename[7];
sprintf(filename, "%03i.jpg", counter);
由于NUL终止符\0
,七个字符串占用8个字符。使数组变大,这样您就不会在数组末尾书写。
if(img == NULL)
{
fprintf(stderr, "Could not create image file\n");
fclose(img);
return 3;
}
如果img
没有打开,则不需要关闭它。另一方面,如果确实打开了,则需要将其关闭。将fclose()
调用移至循环末尾。
答案 1 :(得分:0)
除了答案above,
查看fwrite
函数的语法:
https://en.cppreference.com/w/c/io/fwrite
size_t fwrite( const void *buffer, size_t size, size_t count,
FILE *stream );
根据文档,size
参数是buffer
中每个值的大小。
在您的代码中,您拥有:
fwrite(buffer, 512, 1, img);
问题很明显。
似乎您对fread
进行了同样的操作。该函数的语法为:
https://en.cppreference.com/w/c/io/fread
size_t fread( void *buffer, size_t size, size_t count,
FILE *stream );
在您的代码中,您可以这样做:
fread(buffer, 512, 1, inptr)
但是应该是
fread(buffer, sizeof *buffer, 512, inptr)
顺便说一句,在处理此类文件时,我建议以二进制模式打开它们,以免篡改正在读取的数据。
FILE *inptr = fopen(infile, "rb");
最后,您应该使用fread
的返回值,该值告诉您实际读取的字节数。然后,您可以在fwrite
中使用此值,以确保写入正确的字节数。
答案 2 :(得分:-1)
好的,所以我发现这是我在应该放置的最后一个if语句中放置的NOT运算符:
if (counter != 0)
{
fwrite(buffer, sizeof(buffer), 1, img);
}
但是,对于程序为什么返回分段错误,我仍然感到困惑。
我的理解是,当程序到达此特定的if语句时,由于计数器将被评估为false,因此它不会执行。
程序会在读取整个输入文件返回0以后才结束吗?
细分错误来自哪里?