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

如何将二进制字符串存储到uint8_t类型的比特数组中?

二进制字符串转uint8_t比特数组实现

我有一个仅由0和1组成的二进制字符串"0101011111011111000001001001110110",出于霍夫曼编码需求,需要把字符串中的每个字符以比特形式存入uint8_t数组。直接将二进制字符串写入文件会占用35字节,而比特形式存储仅需约5字节。原代码片段如下:

static uint8_t out_buffer[1024];
static uint32_t bit_pos = 0;

void printbuffer()
{
    printf("Just printing bits\n");
    int i;

    for (i = 0; i < bit_pos; i++) {
        printf("%c", (out_buffer[i / 8] & 1 << (i % 8)) ? '1' : '0');
    }

}
void append_to_bit_array(char* in, int len, uint8_t* buf)
{
    
    int i;
    printbuffer();
    for (i = 0; i < len; i++) {
        if (in[i])
        {
            buf[bit_pos / 8] |= 1 << (bit_pos % 8);
        }
        bit_pos++;
    }
}

原代码问题分析

  • 字符判断逻辑错误:if (in[i])会把字符'0'(ASCII值48,非零)错误判定为需要置1,导致所有字符都被当作'1'存入数组。
  • 存储顺序不符合常规字节位序(可选优化点):原代码将字符串的第一个字符存入uint8_t的最低位(第0位),如果需要按字符串顺序对应字节的高位到低位,需调整移位位置。

修正后的代码

#include <stdio.h>
#include <stdint.h>
#include <string.h>

static uint8_t out_buffer[1024];
static uint32_t bit_pos = 0;

void printbuffer()
{
    printf("当前存储的比特序列:");
    for (uint32_t i = 0; i < bit_pos; i++) {
        // 按原逻辑,从bit_pos=0对应的字节最低位开始打印
        printf("%c", (out_buffer[i / 8] & (1 << (i % 8))) ? '1' : '0');
    }
    printf("\n");
}

void append_to_bit_array(char* in, int len, uint8_t* buf)
{
    // 初始化未使用的字节为0,避免脏数据干扰
    memset(buf + (bit_pos / 8), 0, ((bit_pos + len + 7) / 8) - (bit_pos / 8));
    
    for (int i = 0; i < len; i++) {
        if (in[i] == '1') {
            // 原逻辑:bit_pos第n位对应buf[n/8]的第n%8位(从低位到高位)
            buf[bit_pos / 8] |= 1 << (bit_pos % 8);
            // 若需按字符串顺序对应字节高位到低位,替换为:
            // buf[bit_pos / 8] |= 1 << (7 - (bit_pos % 8));
        }
        bit_pos++;
    }
}

// 测试示例
int main() {
    char bin_str[] = "0101011111011111000001001001110110";
    int str_len = strlen(bin_str);
    
    append_to_bit_array(bin_str, str_len, out_buffer);
    printbuffer();
    
    // 验证存储字节数:(35 +7)/8 = 5字节
    printf("占用字节数:%u\n", (bit_pos + 7) / 8);
    return 0;
}

关键修正说明

  1. 正确判断二进制字符:将if (in[i])改为if (in[i] == '1'),仅当字符是'1'时才在对应比特位上置1。
  2. 初始化缓冲区:使用memset初始化即将写入的字节为0,避免缓冲区原有脏数据干扰结果。
  3. 可选位序调整:如果需要让字符串的第一个字符对应uint8_t的最高位(符合常规字节存储习惯),将移位操作改为1 << (7 - (bit_pos % 8)),同时printbuffer中的判断逻辑也要对应调整为(out_buffer[i / 8] & (1 << (7 - (i % 8))))。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:03:05