CS50 PSET3 恢复分段错误,无法获取输出 JPEG 的代码
CS50 PSET3 Recover segmentation fault, can't get code to output JPEG's
该程序应该从原始文件中恢复 JPEG,我检查过类似的问题,但似乎无法找出我的代码中导致分割错误和无法输出图像的问题。 cs50 中的调试器不起作用。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
typedef uint8_t BYTE;
bool checkheader(BYTE buffer[512]);
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
// save arguments
char *infile = argv[1];
// open input file
FILE *inptr = fopen(infile, "r");
if(inptr == NULL)
{
printf("File could not be read\n");
return 2;
}
//open output file
FILE* img = NULL;
BYTE buffer[512];
int block = 512;
bool newJpeg = false;
bool run = false;
char filename[8];
int filenameCnt = 0;
// run until end of file
while (fread(buffer, 512, 1, inptr) == 1)
{
// read 512 blocks UNTIL FIRST HEADER FOUND, checking to see if first four bytes indicate JPEG
if (newJpeg == false)
{
for (int i = 0; i < block; i++)
{
fread(&buffer[i], 1, 512, inptr);
}
}
// create jpeg file if jpeg header is found
if(checkheader(buffer) == true)
{
sprintf(filename,"%03d.jpg", filenameCnt); // creating a new jpeg
filenameCnt++;
img = fopen(filename, "w"); // making the jpeg writable
run = true;
// write data of block after header
for (int j = 0; j < block - 4; j++)
{
fwrite(&buffer[j+4], 1, 512, img);
}
}
// read and write new blocks into jpeg until new header is found
while (run == true)
{
// read new block
for (int i = 0; i < block; i++)
{
fread(&buffer[i], 1, 512, inptr);
}
// check if new block has header
if(checkheader(buffer) == true)
{
fclose(img); // close current jpeg so new one could be opened
newJpeg = true;
run = false;
}
else
// if not, continue writing new blocks into the current jpeg.
for (int j = 0; j < block; j++)
{
fwrite(&buffer[j], 1, 512, img);
}
}
}
return 0;
}
bool checkheader(BYTE buffer[512])
{
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
return true;
else
return false;
}
它应该输出 50 个 JPEG 文件。任何帮助或意见将不胜感激。谢谢
这个"The debugger in cs50 doesn't function"是否意味着debug50
?也许您在段错误 之后设置了一个断点。段错误出现在这里 fread(&buffer[i], 1, 512, inptr);
(第 51 行)。基本上,它不能"fit" 512 字节的数据在buffer[i] 的地址对于一些i.
一般来说输入文件应该在正好一个地方读取,像这里:while (fread(buffer, 512, 1, inptr) == 1)
这个循环是什么:
for (int i = 0; i < block; i++)
{
fread(&buffer[i], 1, 512, inptr);
}
打算做什么(如果它没有出现段错误!)?它将从 infile 中读取 512 512 字节的块。哇,它肯定会错过一些非常重要的数据,不是吗?
程序需要在一个地方读取inptr
,while
是合适的,然后决定每个读取的块做什么。共有三种选择:
- 丢弃(没有找到第一个jpeg签名)
- 写入当前 jpeg
- 开始一个新的jpeg(它是一个签名块)
请记住,签名块是输出中不可或缺的必要部分。
// write data of block after header
for (int j = 0; j < block - 4; j++)
{
fwrite(&buffer[j+4], 1, 512, img);
}
是 丢弃 header,这将导致损坏的输出。
该程序应该从原始文件中恢复 JPEG,我检查过类似的问题,但似乎无法找出我的代码中导致分割错误和无法输出图像的问题。 cs50 中的调试器不起作用。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
typedef uint8_t BYTE;
bool checkheader(BYTE buffer[512]);
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
// save arguments
char *infile = argv[1];
// open input file
FILE *inptr = fopen(infile, "r");
if(inptr == NULL)
{
printf("File could not be read\n");
return 2;
}
//open output file
FILE* img = NULL;
BYTE buffer[512];
int block = 512;
bool newJpeg = false;
bool run = false;
char filename[8];
int filenameCnt = 0;
// run until end of file
while (fread(buffer, 512, 1, inptr) == 1)
{
// read 512 blocks UNTIL FIRST HEADER FOUND, checking to see if first four bytes indicate JPEG
if (newJpeg == false)
{
for (int i = 0; i < block; i++)
{
fread(&buffer[i], 1, 512, inptr);
}
}
// create jpeg file if jpeg header is found
if(checkheader(buffer) == true)
{
sprintf(filename,"%03d.jpg", filenameCnt); // creating a new jpeg
filenameCnt++;
img = fopen(filename, "w"); // making the jpeg writable
run = true;
// write data of block after header
for (int j = 0; j < block - 4; j++)
{
fwrite(&buffer[j+4], 1, 512, img);
}
}
// read and write new blocks into jpeg until new header is found
while (run == true)
{
// read new block
for (int i = 0; i < block; i++)
{
fread(&buffer[i], 1, 512, inptr);
}
// check if new block has header
if(checkheader(buffer) == true)
{
fclose(img); // close current jpeg so new one could be opened
newJpeg = true;
run = false;
}
else
// if not, continue writing new blocks into the current jpeg.
for (int j = 0; j < block; j++)
{
fwrite(&buffer[j], 1, 512, img);
}
}
}
return 0;
}
bool checkheader(BYTE buffer[512])
{
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
return true;
else
return false;
}
它应该输出 50 个 JPEG 文件。任何帮助或意见将不胜感激。谢谢
这个"The debugger in cs50 doesn't function"是否意味着debug50
?也许您在段错误 之后设置了一个断点。段错误出现在这里 fread(&buffer[i], 1, 512, inptr);
(第 51 行)。基本上,它不能"fit" 512 字节的数据在buffer[i] 的地址对于一些i.
一般来说输入文件应该在正好一个地方读取,像这里:while (fread(buffer, 512, 1, inptr) == 1)
这个循环是什么:
for (int i = 0; i < block; i++)
{
fread(&buffer[i], 1, 512, inptr);
}
打算做什么(如果它没有出现段错误!)?它将从 infile 中读取 512 512 字节的块。哇,它肯定会错过一些非常重要的数据,不是吗?
程序需要在一个地方读取inptr
,while
是合适的,然后决定每个读取的块做什么。共有三种选择:
- 丢弃(没有找到第一个jpeg签名)
- 写入当前 jpeg
- 开始一个新的jpeg(它是一个签名块)
请记住,签名块是输出中不可或缺的必要部分。
// write data of block after header
for (int j = 0; j < block - 4; j++)
{
fwrite(&buffer[j+4], 1, 512, img);
}
是 丢弃 header,这将导致损坏的输出。