CS50恢复分段故障问题

时间:2018-09-11 01:34:38

标签: c segmentation-fault cs50

该程序的目标是从文件中恢复JPG。

我已经在CS50在线课程中解决这个问题大约四到五天了,但我无法弄清楚。我继续遇到细分错误,我也不知道为什么。

我尝试了debug50,发现程序尝试写入新文件时出现错误。为什么这样做我不知道。

我一直在把头撞在墙上的墙上,并且已经完全擦除并重写了多次。任何帮助将不胜感激。

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

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage ./recover file.type\n");
        return 1;
    }

    char *infile = argv[1];
    FILE *inptr = fopen(infile, "rb");


    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open file designated to be recovered\n");
        fclose(inptr);
        return 2;
    }

    int counter = 0;
    FILE *img;

    uint8_t buffer[512];

    while (fread(buffer, sizeof(*buffer), 512, inptr))
    {
        if (buffer[0] == 0xff &&
            buffer[1] == 0xd8 &&
            buffer[2] == 0xff &&
            (buffer[3] & 0xf0) == 0xe0)
        {
            if (counter > 0)
            {
                fclose(img);
            }

            char filename[8];
            sprintf(filename, "%03i.jpg", counter);

            img = fopen(filename, "w");

            counter++;
        }

        if (counter !=0)
        {
            fwrite(buffer, sizeof(*buffer), 512, img);
        }
    }
    fclose(img);
    fclose(inptr);
    return 0;
}

3 个答案:

答案 0 :(得分:1)

char filename[7];
sprintf(filename, "%03i.jpg", counter);

由于NUL终止符\0,七个字符串占用8个字符。使数组变大,这样您就不会在数组末尾书写。

if(img == NULL)
{
    fprintf(stderr, "Could not create image file\n");
    fclose(img);
    return 3;
}

如果img没有打开,则不需要关闭它。另一方面,如果确实打开了,则需要将其关闭。将fclose()调用移至循环末尾。

答案 1 :(得分:0)

除了答案above

查看fwrite函数的语法:

https://en.cppreference.com/w/c/io/fwrite

size_t fwrite( const void *buffer, size_t size, size_t count,
               FILE *stream );

根据文档,size参数是buffer中每个值的大小。

在您的代码中,您拥有:

fwrite(buffer, 512, 1, img);

问题很明显。

似乎您对fread进行了同样的操作。该函数的语法为:

https://en.cppreference.com/w/c/io/fread

size_t fread( void          *buffer, size_t size, size_t count,
              FILE          *stream );

在您的代码中,您可以这样做:

fread(buffer, 512, 1, inptr)

但是应该是

fread(buffer, sizeof *buffer, 512, inptr)

顺便说一句,在处理此类文件时,我建议以二进制模式打开它们,以免篡改正在读取的数据。

FILE *inptr = fopen(infile, "rb");

最后,您应该使用fread的返回值,该值告诉您实际读取的字节数。然后,您可以在fwrite中使用此值,以确保写入正确的字节数。

答案 2 :(得分:-1)

好的,所以我发现这是我在应该放置的最后一个if语句中放置的NOT运算符:

    if (counter != 0)
    {
        fwrite(buffer, sizeof(buffer), 1, img);
    }

但是,对于程序为什么返回分段错误,我仍然感到困惑。

我的理解是,当程序到达此特定的if语句时,由于计数器将被评估为false,因此它不会执行。

程序会在读取整个输入文件返回0以后才结束吗?

细分错误来自哪里?