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

如何将含连续5位无符号数的压缩二进制文件读入整数数组

处理连续5位无符号数的二进制文件读取

直接用fread读取会出错,因为fread是按**字节(8位)**为单位读取数据,而你的文件是把5位无符号数连续打包存储的——单个字节里可能包含1个完整的5位数据,或者和相邻字节拼接出完整的5位数据,因此必须手动解析位流来提取每个5位数值。

核心思路

  1. 先读取整个文件的字节数据到缓冲区(或逐字节读取),维护一个位指针记录当前处理到字节的第几位。
  2. 每次从当前位置提取5位:如果当前字节剩余位数不足5位,就从下一个字节补够剩余位数。
  3. 将提取的5位二进制转换成无符号整数,存入目标数组。
  4. 总有效数的个数为 (文件总字节数 × 8) ÷ 5,不足5位的末尾数据直接丢弃(因为是连续的5位无符号数,不存在不完整的有效数据)。

示例代码(C语言)

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

#define BITS_PER_NUMBER 5

int main() {
    FILE *fp = fopen("your_data.bin", "rb");
    if (!fp) {
        perror("Failed to open file");
        return 1;
    }

    // 获取文件总大小
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    // 分配缓冲区存储所有字节数据
    unsigned char *byte_buffer = malloc(file_size);
    if (!byte_buffer) {
        perror("Failed to allocate buffer");
        fclose(fp);
        return 1;
    }

    // 读取全部字节到缓冲区
    size_t read_bytes = fread(byte_buffer, 1, file_size, fp);
    if (read_bytes != file_size) {
        perror("Failed to read full file");
        free(byte_buffer);
        fclose(fp);
        return 1;
    }
    fclose(fp);

    // 计算可提取的5位无符号数总个数
    long total_bits = file_size * 8;
    long num_count = total_bits / BITS_PER_NUMBER;
    unsigned int *num_array = malloc(num_count * sizeof(unsigned int));
    if (!num_array) {
        perror("Failed to allocate number array");
        free(byte_buffer);
        return 1;
    }

    int current_byte = 0;
    int current_bit = 0; // 0表示当前字节的最高位,7表示最低位

    for (long i = 0; i < num_count; i++) {
        unsigned int value = 0;
        int remaining_bits = BITS_PER_NUMBER;

        while (remaining_bits > 0) {
            // 当前字节剩余可用位数
            int available_bits = 8 - current_bit;
            // 本次提取的位数:取剩余需要的位数和当前可用位数的较小值
            int take = (remaining_bits < available_bits) ? remaining_bits : available_bits;

            // 生成掩码提取目标位
            unsigned char mask = (0xFF >> (8 - take)) << (available_bits - take);
            unsigned char extracted_bits = (byte_buffer[current_byte] & mask) >> (available_bits - take);

            // 将提取的位拼接到结果中
            value = (value << take) | extracted_bits;

            remaining_bits -= take;
            current_bit += take;

            // 当前字节处理完毕,切换到下一个字节
            if (current_bit == 8) {
                current_byte++;
                current_bit = 0;
            }
        }

        num_array[i] = value;
    }

    // 验证:打印前10个数值(可根据需求修改)
    for (long i = 0; i < (num_count > 10 ? 10 : num_count); i++) {
        printf("Num %ld: %u\n", i, num_array[i]);
    }

    // 释放内存
    free(byte_buffer);
    free(num_array);
    return 0;
}

为什么你之前的尝试会失败

  • 直接用fread读取得到的是8位字节值,而不是打包的5位数据,自然数值错误。
  • 数组末尾的空项是因为你可能按文件字节数来分配数组大小,但实际有效5位数值的个数是总位数÷5,远小于字节数,导致数组后半部分未被填充。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:05:26