0

基本上我正在尝试从文件中读取内容,其中内容存储在 512 字节的块中。我知道为什么会出现分段错误,但由于我不知道 JPEG 文件的大小,所以我不知道我在哪里遇到了问题。调试器在调用 fread 后确实停止了,尽管我不知道它为什么会这样做。

运行调试器时,循环可能会运行 40 多次,然后由于分段错误而崩溃。

这是我目前正在使用的代码:缓冲区已分配大小为 512

int counter = 0;
char *fileName = (char *) malloc(sizeof(int));
//sprintf(fileName, "%03i.jpg", counter);

FILE *img = NULL;

while(feof(p) == 0)
{
    fread(buffer, sizeof(char), 512, p);

    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && ((buffer[3] & 0xf0) == 0xe0)) //checks if the first four bytes match
    {
        if(img == NULL)
        {
            sprintf(fileName, "%03i.jpg", counter);
            img = fopen(fileName, "w");
            fwrite(buffer, sizeof(char), 512, img);
        }
        else
        {
            counter++;
            sprintf(fileName, "%03i.jpg", counter);
            img = fopen(fileName, "w");
            fwrite(buffer, sizeof(char), 512, img);
        }
    }
    else
    {
        //continue writing to existing file
        if(img == NULL)
        {
            continue;
        }
        else
        {
            fwrite(buffer, sizeof(char), 512, img);
        }
    }

    if(feof(p) > 0)
    {
        fclose(p);
        fclose(img);
        free(fileName);
        free(buffer);
        return 0;
    }
4

1 回答 1

2

您一次只需要读取 512 个字节。

而且,您循环检查分隔符并在看到一个时更改输出文件。

由于分隔符在 512 字节边界上对齐,因此您一次只想读取 512 个字节——不多也不少。

正如我在热门评论中提到的那样,已经有很多答案了。但是,我回答了一个类似的问题,并在下面生成了以下调试代码:

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

bool magictag(uint8_t *);

int
main(int argc, char *argv[])
{

    if (argc != 2) {
        fprintf(stderr, "Usage:./recover image\n");
        return 1;
    }
    FILE *memorycard = fopen(argv[1], "r");

    if (!memorycard) {
        fprintf(stderr, "File cannot be opened\n");
        return 2;
    }

    int file_no = 0;
    int b;
    int code = 0;
    uint8_t buf[1000];

    FILE *jpeg = NULL;

    // While haven't reached EOF
    while (1) {
        b = fread(buf, 512, 1, memorycard);
        if (b == 0)
            break;

        int startflg = magictag(buf);

        if (startflg) {
            if (jpeg != NULL)
                fclose(jpeg);

            char outfile[50];
            sprintf(outfile, "%03i.jpg", file_no);
            ++file_no;

            jpeg = fopen(outfile,"w");
            if (jpeg == NULL) {
                fprintf(stderr, "jpg cannot be created\n");
                code = 3;
                break;
            }
        }

        if (jpeg != NULL)
            fwrite(buf, 512, 1, jpeg);
    }

    if (jpeg != NULL)
        fclose(jpeg);

    fclose(memorycard);

    return code;
}

bool
magictag(uint8_t *c)
{
    bool ret = false;

    do {
        if (c[0] != 0xFF)
            break;
        if (c[1] != 0xD8)
            break;
        if (c[2] != 0xFF)
            break;
        if ((c[3] & 0xF0) != 0xE0)
            break;
        ret = true;
    } while (0);

    return ret;
}

请注意,实际问题在这里:我恢复的图像在 CS50 PSET4 Recover 中不匹配

我没有发布上面的代码,因为那个 OP 已经从那里的评论中解决了这个问题。

于 2020-11-02T01:40:55.013 回答