c语言 - CS50 的 pset4 上的分段故障



我把自己逼疯了,试图弄清楚我的代码发生了什么。

我目前在 CS50 的 pset4 中。恢复挑战。

对于那些不知道它是关于什么的人: 我们得到了一个名为card的文件.raw其中有一些已删除的照片。我们的任务是实施一个程序,该程序可以进行一些取证(田园诗般的)并恢复丢失的照片。

特此附上我的代码:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: ./recover filen");
return 1;
}
//declaring pointer infile and giving the address of argv[1];
char *infile = argv[1];
//Opening file
FILE *raw_data; 
raw_data = fopen(infile, "r");
//Checking for NULL error
if(raw_data == NULL)
{
fprintf(stderr, "Could not open file.n");
return 2;
}

uint8_t buffer[512];                //Delcaring unsigned int variable type. Array of 512 bytes.
int counter = 0;                    //Declaring counter for counting jpegs files
FILE *outfile;                    //Setting pointer named outfile for printing here
char filename[8];                 //declaring 'filename' variable for storing the file's name

//While we can reads blocks of memory of 512 bytes from raw_data (aka the address from the infile) into buffer:
while (fread(buffer, 512, 1, raw_data))
{
//Condition for tracking the first bytes that form a JPEG file
if(buffer[0] == 0xff && 
buffer[1] == 0xd8 && 
buffer[2] == 0xff &&
(buffer[3] & 0xf0) == 0xe0)
{

if(counter == 0)                              //If this is the 1st file, then name the file with 
//counter value with 3 digits (%03d)
{                                             
sprintf(filename, "%03d.jpg", counter);   // And 3 digits (%i3)
outfile = fopen(filename, "w");           //Open file named outfile in write mode
counter++;
}
else                              //If this is not the first JPG opened, firstly close the 
{                                 // current open file, and then open a new one with the 
fclose(outfile);              // current counter value and 3 digits for its name
sprintf(filename, "%03d.jpg", counter);
outfile = fopen(filename, "w");   //Open file named 'outfile' in write mode 
counter++;
}

}
fwrite(buffer, 1, sizeof(buffer), outfile); /* Write function that takes buffer data (aka the 
pointer to the array of elements to be written, 
writes 1 byte of elements of the syze buffer (512)
and it writes it to the output, aka 'outfile' */
}
fclose(outfile);            //Remember to close the last file once we get out of the while-loop
}

这是棘手的部分:

我已经成功恢复了所有有问题的图像。 但是,如果我多次运行代码,例如 5 次,我最终会遇到分段错误。

当我运行 check50时,我收到以下消息(在成功运行和 check50 veredict 之后,我将附加一个包含分段错误的图像)。点击这里查看图片

我就是不明白。我怀疑记忆可能有些问题,但我不知道是什么。

非常感谢您的时间和帮助。StackOVerFlow总是一个寻求指导的好地方。

编辑

如果我在分段错误提示后运行echo $?,则得到的值为 139。

这是终端提示截图

编辑

正如@Thomas Dickey指出的那样,程序正在写入文件,无论是否有打开的文件。

我已经更新并修复了一些我的代码以使其更干净,并添加了一个 if 条件以修复它。

这是解决方案:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: ./recover filen");
return 1;
}
//declaring pointer infile and giving the address of argv[1];
char *infile = argv[1];
//Opening file
FILE *raw_data; 
raw_data = fopen(infile, "r");
//Checking for NULL error
if(raw_data == NULL)
{
fprintf(stderr, "Could not open file.n");
return 2;
}
uint8_t buffer[512];                //Delcaring unsigned int variable type. Array of 512 bytes.
int counter = 0;                    //Declaring counter for counting jpegs files
FILE *outfile;                    //Setting pointer named outfile for printing here
char filename[8];                 //declaring 'filename' variable for storing the file's name

//While we can reads blocks of memory of 512 bytes from raw_data (aka the address from the infile) into buffer:
while (fread(buffer, 512, 1, raw_data))
{
//Condition for tracking the first bytes that form a JPEG file
if(buffer[0] == 0xff && 
buffer[1] == 0xd8 && 
buffer[2] == 0xff &&
(buffer[3] & 0xf0) == 0xe0)
{
if(counter != 0)                              
{           
fclose(outfile);                      //If this is not the first JPG opened, close previous file
}
sprintf(filename, "%03d.jpg", counter);  //print stream to 'filename' the value of 'counter' in 3 digits  
outfile = fopen(filename, "w");           //Open file named outfile in write mode
counter++;                                //Add 1 to counter
} 
if(counter != 0)                          //Don't start writing on a file until the first jpeg is found
{
fwrite(buffer, sizeof(buffer), 1, outfile);          /* - Write function that takes buffer data
(aka the array of elements to be written) , 
- Write a block of 512 bytes of elements 
(aka the size of buffer), 
- 1 block of 512 bytes at a time, 
- And it writes it to the output, aka 'outfile' */
}                                                         
}
fclose(outfile);            //Remember to close the last file once we get out of the while-loop
return 0;

}

程序仅在标头看起来正常时打开输出文件,但无论如何都会写入输出。 如果您读取的文件没有 jpeg 标头,它将中断。

相关内容

  • 没有找到相关文章