如何将二进制字符串存储到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; }
关键修正说明
- 正确判断二进制字符:将
if (in[i])改为if (in[i] == '1'),仅当字符是'1'时才在对应比特位上置1。 - 初始化缓冲区:使用
memset初始化即将写入的字节为0,避免缓冲区原有脏数据干扰结果。 - 可选位序调整:如果需要让字符串的第一个字符对应
uint8_t的最高位(符合常规字节存储习惯),将移位操作改为1 << (7 - (bit_pos % 8)),同时printbuffer中的判断逻辑也要对应调整为(out_buffer[i / 8] & (1 << (7 - (i % 8))))。
内容的提问来源于stack exchange,提问作者Veeru Veeravalli
相关产品推荐
相关产品推荐

