这是一个接受文件名作为输入的程序,应恢复该文件中的所有 jpegs 。它一次读取 512字节,检查新jpeg的开始。
程序编译,当我运行它时,虽然它给出了分段错误。请帮我解决这个问题。
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define BLOCK 512
int main(int argc, char *argv[])
{
// buffer is 512 bytes
uint8_t buffer[512];
// declaring Filename;
char Filename[8];
if (argc != 2)
{
fprintf(stderr, "Input should be exactly one argument!\n");
return 1;
}
char *infile = argv[1];
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
fprintf(stderr, "Could not open file.\n");
return 2;
}
int jpegcounter = 0;
FILE *img;
// check if return value fread is equal to 1
while (fread(&buffer, BLOCK, 1, inptr) == 1)
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
// if this is the first jpeg code encountered
if (jpegcounter == 0)
{
// create first jpeg file
sprintf(Filename, "%03d.jpg", jpegcounter);
// open the file in writing mode
img = fopen(Filename, "w");
// write the 512 bytes block into the file
fwrite(&buffer, BLOCK, 1, img);
}
// if this is not the first jpeg code encountered
else
{
fclose(img);
// add 1 to jpegcounter for new jpeg name
jpegcounter ++;
// create the next jpeg file
sprintf(Filename, "%03d.jpg", jpegcounter);
// open the file in writing mode
img = fopen(Filename, "w");
// write the 512 bytes block into the file
fwrite(&buffer, BLOCK, 1, img);
}
}
// if no new jpeg code is encountered
else if (buffer[0] != 0xff || buffer[1] != 0xd8 || buffer [2] != 0xff || (buffer[3] & 0xf0) != 0xe0)
{
// write the 512 bytes block into the currently opened file
fwrite(&buffer, BLOCK, 1, img); // this is the line debugger points out as an error
}
}
// close current image
fclose(img);
// close memory card file
fclose(inptr);
// success
return 0;
}
答案 0 :(得分:0)
问题可能是img
未打开。有两种方法可以实现。
在img = fopen(Filename, "w");
的两个实例中,您都没有检查它是否已打开。它可能会失败。
第二种情况是,如果第一个if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
为假,else if (buffer[0] != 0xff || buffer[1] != 0xd8 || buffer [2] != 0xff || (buffer[3] & 0xf0) != 0xe0)
为真,则img
将不会打开。
查看没有所有代码的代码,您可以清楚地看到问题。
FILE *img;
while (fread(&buffer, BLOCK, 1, inptr) == 1)
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
// The code in here might not happen.
}
else if (buffer[0] != 0xff || buffer[1] != 0xd8 || buffer [2] != 0xff || (buffer[3] & 0xf0) != 0xe0)
{
// img might be uninitialized
fwrite(&buffer, BLOCK, 1, img);
}
}
通过观察您总是fwrite(&buffer, BLOCK, 1, img);
可以大大简化代码。唯一改变的是它是否属于新文件。
如果我们将img
初始化为NULL,我们可以确保始终打开文件句柄。
int jpegcounter = 0;
// Set img to NULL so we can know to open the first file.
// Don't open it here because the input file might be empty.
FILE *img = NULL;
while (fread(&buffer, BLOCK, 1, inptr) == 1)
{
// If we need a new file, or if one isn't opened.
if ( is_new_jpeg(buffer) || img == NULL ) {
// Close the previous file, if any.
if( img != NULL ) {
fclose(img);
}
// Open a new file.
img = open_new_jpeg_file( jpegcounter );
jpegcounter++;
}
fwrite(&buffer, BLOCK, 1, img);
}
// If the input was empty we might not have opened an image.
if( img != NULL ) {
fclose(img);
}
fclose(inptr);
请注意,我已经移动了打开jpeg文件的逻辑,并检测到文件中的各种标志为自己的函数。这极大地简化了代码,并使测试这些组件变得容易。
答案 1 :(得分:0)
我做了以下修改,以避免将args传递给gdb。
False
这是我放在调试目录中的一个jpeg。 OP代码有效。我成功地完成了代码,直到我返回0;
唯一的问题是原始文件和输出文件之间存在109个字节的差异。可能是EOF条件。
可能是传递的args中存在拼写错误