在 windows 文件结束前到达 EOF

Reaching EOF before end of file on windows

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

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

    FILE *file = fopen(argv[1], "r");
    if (file == NULL)
    {
        fprintf(stderr, "Could not open file\n");
        return 1;
    }
    unsigned char buffer[size];
    int count = 0;
    FILE *jpeg = NULL;

    while(fread(buffer, size, 1, file))
    {
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            char image[7];
            if (count != 0)
            {
                fclose(jpeg);
            }
            sprintf(image, "%03i.jpg", count);
            jpeg = fopen(image, "w");
            if (jpeg == NULL)
            {
                fprintf(stderr, "couldn't open file\n");
                return 1;
            }
            count++;
        }
        if (count != 0)
        {
            fwrite(&buffer, size, 1, jpeg);
        }
    }
    fclose(file);

}

此代码在 card.raw 中查找 jpeg 当我 运行 上面的代码在 linux 时,它的 运行ning 是正确的。但是在 windows 上,代码只读取 card.raw 文件的前三个 512 字节块。 我做错了什么? 我也在 linux 上使用 clang。 windows 我正在使用 gcc。

首先,二进制文件应该用二进制模式打开。这意味着您应该为 fopen() 模式使用 "rb""wb" 而不是 "r""w"。否则,换行符可能会被意外转换,并且可能会在字节 0x1a.

处停止

其次,对数组 char image[7];sprintf(image, "%03i.jpg", count); 是不好的。 sprintf() 的结果将是(至少)7 个字符,因此需要具有 8 个或更多元素的数组来存储包含终止空字符的字符串。为了安全起见,您应该使用 snprintf(),它接受缓冲区大小。