gpt4 book ai didi

c - cs50 recover.c 中的段错误

转载 作者:行者123 更新时间:2023-11-30 16:48:37 32 4
gpt4 key购买 nike

这是一个接受文件名作为输入的程序,应该恢复所有 JPEG 在那个文件上。它显示 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;
}

最佳答案

问题很可能是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 文件和检测文件中各种标志的逻辑移到了它们自己的函数中。这极大地简化了代码并使测试这些组件变得容易。

关于c - cs50 recover.c 中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42889257/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com