You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fread读取BMP文件数据不完整且无法打印的技术问题

问题分析与解决

核心问题1:fread 参数顺序错误

fread 的标准原型是:

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

参数含义:

  • size:单个元素的字节大小
  • count:要读取的元素总数

你的代码中写反了这两个参数:

f_size = fread(str, 8, sizeof(char), fptr_stego);

这段代码会尝试读取1个大小为8字节的元素,而非8个1字节的字符。一旦文件中当前位置无法提供完整的8字节连续数据(或受文本模式干扰),就会返回小于1的结果,这就是你只读到1字节的直接原因。

正确写法应为:

f_size = fread(str, sizeof(char), 8, fptr_stego);

核心问题2:以文本模式打开二进制文件

BMP是二进制格式文件,你用"r"文本模式打开时,会触发系统的文本转换逻辑:

  • Windows下会自动把\r\n转换为\n,破坏字节偏移的准确性
  • 任何位置的0x1A(ASCII终止符)会被视为文件结束,提前终止读取

必须改用二进制模式打开:

fptr_stego = fopen("stego.bmp", "rb");

附加问题:不可打印字符的输出

你用%c打印str[0],如果该字节是不可打印字符(比如0x00、控制字符等),终端不会显示任何内容。可以改用十六进制格式查看实际字节值:

printf("First byte data: 0x%02X\n", (unsigned char)str[0]);

修正后的完整代码

#include<stdio.h>
int main()
{
    FILE *fptr_stego;
    FILE *fptr_text;
    size_t f_size = 0;
    char str[8];

    // 以二进制模式打开图像文件
    fptr_stego = fopen("stego.bmp", "rb");
    if(fptr_stego == NULL)
    {   
        printf("FAILED to open stego file\n");
        return 0;
    }   

    fptr_text = fopen("decode.txt", "w");
    if(fptr_text == NULL)
    {   
        printf("FAILED to open text file\n");
        return 0;
    }   

    printf("Successfully opened both files\n");

    // 验证指针移动是否成功
    if(fseek(fptr_stego, 54, SEEK_SET) != 0) {
        printf("fseek failed\n");
        return 0;
    }
    printf("File pointer location before reading %ld\n", ftell(fptr_stego));
    
    // 修正fread参数顺序,读取8个char元素
    f_size = fread(str, sizeof(char), 8, fptr_stego);
    if(f_size != 8)
    {   
        printf("Unable to fetch 8 bytes\n%ld bytes read at %ld position\n", f_size, ftell(fptr_stego));
        printf("First byte data: 0x%02X\n", (unsigned char)str[0]);
        return 0;
    }

    // 将读取的内容写入文本文件
    fwrite(str, sizeof(char), 8, fptr_text);

    fclose(fptr_stego);
    fclose(fptr_text);

    printf("Data read successfully\n");
    return 0;
}

额外验证建议

  • 用hd stage.bmp确认第54到61字节的内容,修正后的代码应能正确读取这些字节
  • 若仍有问题,可检查fseek的返回值,确认指针是否成功移动到目标位置

内容的提问来源于stack exchange,提问作者Siddharth Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:03:10