CS50恢复分段故障问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
");
        return 1;
    }

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


    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open file designated to be recovered
");
        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;
}
答案
char filename[7];
sprintf(filename, "%03i.jpg", counter);

由于NULL终止符qazxsw poi,七个字符的字符串占用8个字符。使数组变大,这样就不会写出它的末尾。

如果if(img == NULL) { fprintf(stderr, "Could not create image file "); fclose(img); return 3; } 没有打开你就不需要关闭它。另一方面,如果它确实打开,那么你需要关闭它。将img调用移动到循环的末尾。

另一答案

除了答案fclose()

看看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中使用此值,以确保编写正确的字节数。

另一答案

好的,所以我发现当我应该放的是最后一个if语句时,它是NOT运算符:

fwrite

然而,我仍然对程序返回分段错误的原因感到困惑。

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

程序然后只是在读取整个输入文件返回0后才结束?

分段错误来自哪里?

以上是关于CS50恢复分段故障问题的主要内容,如果未能解决你的问题,请参考以下文章

装配分段故障恢复

CS50 Speller 中的分段错误。为啥?

QApplication 执行分段故障错误

CS50 PSet 2:Vigenere 密码分段错误

为啥在此 C++ 代码中出现分段错误?

访问全局数组会导致分段错误