PSET 4 恢复分段故障 CS50
PSET 4 Recover SEGMENTATION FAULT CS50
我在读取文件和写入文件方面遇到了一些困难。几天来我一直在研究这个问题,但我似乎无法理解。该程序应该从存储卡中恢复一些 jpeg 文件。使用以下代码,我不断遇到分段错误。你们能看出我错在哪里吗?下面是我的代码:
希望大家帮帮忙!
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
int main(int argc, char *argv[])
{
//Ensure only one command line argument//
if (argc != 2)
{
printf("Usage: ./recover filename\n");
return 1;
}
//Open File//
FILE *file = fopen(argv[1], "r");
if (file == NULL)
{
printf("File not working\n");
return 1;
}
//Create buffer of size 512 bytes to store data from file that is being read//
unsigned char buffer[512];
//Set Bool value of already found first jpeg to false//
bool already_found_jpeg = false;
//Create filename length of 8 that will be of new jpegs
char filename[8];
FILE *img = NULL;
//num_of_imgs counter//
int num_of_imgs = 0;
while(fread(buffer, 512, 1, file) == 1)
{
//If start of new jpeg//
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
//If first jpeg, start writing the very first file//
if (already_found_jpeg == false)
{
sprintf(filename, "%03i.jpg", num_of_imgs);
img = fopen(filename, "w");
if (img == NULL)
{
return 3;
}
//Write from buffer into new file//
fwrite(&buffer, 512, 1, img);
num_of_imgs ++;
already_found_jpeg = true;
}
//Else if already found a jpeg meaning it's not the first jpeg then close file, so you can open up a new file that can be written too
else if (already_found_jpeg == true)
{
fclose(img);
sprintf(filename, "%03i.jpg", num_of_imgs);
img = fopen(filename, "w");
if (img == NULL)
{
return 3;
}
//Write from buffer into new file//
fwrite(&buffer, 512, 1, img);
num_of_imgs ++;
}
}
//else if not found the jpeg headers and already found first jpeg keep writing to file
else
{
if (already_found_jpeg == true)
{
fwrite(&buffer, 512, 1, img);
}
}
//Close all files//
fclose(file);
fclose(img);
}
}
问题
在 while 循环的第一次迭代结束时,您正在 关闭 file
和 img
。这意味着这些指针的值变为 NULL。在下一次迭代中,缓冲区从 NULL 指针读取(因为我们关闭了 file
,它没有指向任何内容)。基本上,取消引用空指针会导致分段错误。
解决方案
如果将这段代码移到 while 循环之外,它将起作用。 (使用 CS50 IDE 测试)
//Close all files//
fclose(file);
fclose(img);
这对我来说是一个很好的练习,可以回顾我在 CS50 中所做的事情 - 恢复。 :)
我在读取文件和写入文件方面遇到了一些困难。几天来我一直在研究这个问题,但我似乎无法理解。该程序应该从存储卡中恢复一些 jpeg 文件。使用以下代码,我不断遇到分段错误。你们能看出我错在哪里吗?下面是我的代码:
希望大家帮帮忙!
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
int main(int argc, char *argv[])
{
//Ensure only one command line argument//
if (argc != 2)
{
printf("Usage: ./recover filename\n");
return 1;
}
//Open File//
FILE *file = fopen(argv[1], "r");
if (file == NULL)
{
printf("File not working\n");
return 1;
}
//Create buffer of size 512 bytes to store data from file that is being read//
unsigned char buffer[512];
//Set Bool value of already found first jpeg to false//
bool already_found_jpeg = false;
//Create filename length of 8 that will be of new jpegs
char filename[8];
FILE *img = NULL;
//num_of_imgs counter//
int num_of_imgs = 0;
while(fread(buffer, 512, 1, file) == 1)
{
//If start of new jpeg//
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
//If first jpeg, start writing the very first file//
if (already_found_jpeg == false)
{
sprintf(filename, "%03i.jpg", num_of_imgs);
img = fopen(filename, "w");
if (img == NULL)
{
return 3;
}
//Write from buffer into new file//
fwrite(&buffer, 512, 1, img);
num_of_imgs ++;
already_found_jpeg = true;
}
//Else if already found a jpeg meaning it's not the first jpeg then close file, so you can open up a new file that can be written too
else if (already_found_jpeg == true)
{
fclose(img);
sprintf(filename, "%03i.jpg", num_of_imgs);
img = fopen(filename, "w");
if (img == NULL)
{
return 3;
}
//Write from buffer into new file//
fwrite(&buffer, 512, 1, img);
num_of_imgs ++;
}
}
//else if not found the jpeg headers and already found first jpeg keep writing to file
else
{
if (already_found_jpeg == true)
{
fwrite(&buffer, 512, 1, img);
}
}
//Close all files//
fclose(file);
fclose(img);
}
}
问题
在 while 循环的第一次迭代结束时,您正在 关闭 file
和 img
。这意味着这些指针的值变为 NULL。在下一次迭代中,缓冲区从 NULL 指针读取(因为我们关闭了 file
,它没有指向任何内容)。基本上,取消引用空指针会导致分段错误。
解决方案
如果将这段代码移到 while 循环之外,它将起作用。 (使用 CS50 IDE 测试)
//Close all files//
fclose(file);
fclose(img);
这对我来说是一个很好的练习,可以回顾我在 CS50 中所做的事情 - 恢复。 :)