读取 C: ftell 中的二进制文件返回的结果有时会相差 1



我正在尝试读取以下格式的二进制文件:

图像数量 [4 字节整数]

宽度 [4 字节整数]
高度 [4 字节整数]
灰度数据 [宽度 * 高度字节]
(更多同类型的元素(

这是调用的第一个函数:

int process_file(const char *filename) {
    FILE *input_file = fopen(filename, "r");
    //Get number of images
    unsigned int number_of_images = read_int_from_file(input_file);
    //Allocate memory for all images
    struct image *images = malloc(sizeof(struct image) * number_of_images);
    read_images(images, number_of_images, input_file)
}

这是任何想知道的人image结构:

struct image {
    unsigned int width;
    unsigned int height;
    unsigned char *data;
};

这就是read_int_from_file所做的:

static unsigned int read_int_from_file(FILE *file) {
    unsigned char chars[4];
    if (fread(&chars, sizeof(char), 4, file) != 4) {
        fprintf(stderr, "Couldn't read enough bytes!n");
        return 0;
    }
    //Calculations follow that return right numbers
    return out;
}

这就是其余的:

static int read_images(struct image *images, unsigned int number_of_images, FILE * file) {
    struct image *current_image = images;
    int i;
    for (i = 0; i < number_of_images; i++) {
        read_image(current_image++, file)
    }
    return EXIT_SUCCESS;
}
static int read_image(struct image *image, FILE *file) {
    static long int expected_position = 4;
    if (ftell(file) != expected_position) {
        fprintf(stderr, "Reading @ %lu when should be @ %lu!",
                ftell(file), expected_position);
        exit(EXIT_FAILURE);
    }
    unsigned int width = read_int_from_file(file);
    unsigned int height = read_int_from_file(file);
    unsigned int size = width * height;
    unsigned char *data = malloc(sizeof(char) * size);
    if (data) {
        if (fread(data, sizeof(char), size, file) != size) {
            exit(EXIT_FAILURE);
        }
        image->width = width;
        image->height = height;
        image->data = data;
        expected_position += 2 * 4 + width * height;
        return EXIT_SUCCESS;
    } else {
        exit(EXIT_FAILURE);
    }
}

问题是文件指针有时在不应该这样做的时候继续前进,即我正在点击ftell(file) != expected_position.我在大量成功阅读后得到了它,但在结束之前也有一些很好的时间。

有谁知道为什么会这样?我的意思是,即使数字是错误的,也不应该发生,不是吗?谢谢!

MS-DOS的行尾序列是回车,新行(CR NL0x0D, 0x0A(,Unix只使用新行(NL0x0A(。

更改行

FILE *input_file = fopen(filename, "r");

FILE *input_file = fopen(filename, "rb");

否则,fread()函数用于将CR NL转换为NL,在POSIX标准"IEEE Std 1003.1-1988"之前的Unix系统上。

在MS-DOS,Windows及其衍生产品上,它将NL转换为CR NL

这些翻译会导致您对文件位置的看法与ftell()的计算不同。

您需要按如下方式打开二进制文件:

//                                   v
FILE *input_file = fopen(filename, "rb");

最新更新