【问题标题】:Writing specific bits to a binary header将特定位写入二进制标头
【发布时间】:2018-11-08 19:31:52
【问题描述】:

假设我想创建特定长度的二进制文件,使用前 4 位定义类型(应该允许 16 种不同的类型)和后 60 位定义内容。

如何继续在 C 中构建它?我很难找到在 C 中执行此操作的任何示例(正确解释它)(我以前没有使用过这么低级别的 C,我正试图弄湿我的脚......)

我可以创建一个char[8] 并手动设置每个位,例如

/** Set bit in any sized bit block.
 *
 * @return   none
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 *
 * @note    Please note that this function does not know the size of the
 *          bitmap and it cannot range check the specified bit number.
 */
void SetBit(int bit, unsigned char *bitmap)
{
    int n, x;

    x = bit / 8;                        // Index to byte.
    n = bit % 8;                        // Specific bit in byte.

    bitmap[x] |= (1 << n);      // Set bit.
}

以上代码来自storing a bit in a bit of character array in C linux

【问题讨论】:

  • char name[16]; 有 16 字节 * 8 位/字节 = 128 位。 char name[8]; 应该足够了。
  • 16 个字符的数组将是 16 x 8 = 128 位
  • 数学让我失望了!我会编辑上面的帖子来修复它!
  • 是什么类型的?您要存储的数字范围是多少?
  • 4 位类型可以是任何可以用 4 位空间表示的东西......猜猜这是 0-15 之间的任何东西

标签: c


【解决方案1】:

我会创建一个特定于任务的函数,然后只使用掩码。

void setType(uint8_t type, uint8_t* header)
{
    header[0] = (header[0] & 0x0f) | (type << 4);
}

// To use:

uint8_t header[8]; 
setType(3, header);

我会创建一个类似的函数来设置标题的每个字段。

以上假设“前四位”是指标头第一个字节的最高有效位,而不是标头第一个字节的最低有效位。

【讨论】:

  • 这似乎对我有用!回读类型就像(header[0] &amp; 0xf0) &gt;&gt; 4); 一样简单,对吧?
  • @MadsRC 是的。但我会再次编写一个函数来封装它。
【解决方案2】:

你可以有类似这个函数的东西来帮助你设置一个特定的半字节(半字节是 4 位数据。1 字节(8 位)是 2 字节,可能这让你感到困惑)。这意味着你只需要通过您的 char[x] 字节指定您需要更改字节的左侧或右侧部分:

int set_nibble(unsigned char* dest,unsigned char src,nibble_side side)
{
    if (side == left_hand )
    {
        *dest = ((*dest & 0x0f) | (src<<4));
        return 0;
    }
    if (side == right_hand )
    {

        *dest = ((*dest & 0xf0) | (src));
        return 0;
    }
    return -1;
}

nibble_side 参数类似于

typedef enum nibble_side_t
    {
        right_hand, left_hand
    } nibble_side;

Herehere 两个不错的二进制 AND 操作指南。在进行此类操作之前,您必须对使用它来过滤所需的数据感到满意。

【讨论】:

  • 如果您在创建枚举时遇到麻烦,您应该使用它的常量进行比较:if (side == 1) -> if (side == left_hand)
  • 是的,谢谢。我什至不记得这段代码的历史了。刚刚从我的仓库中回忆起来。我想给他一个例子,说明你如何使用 & 作为过滤器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-07
相关资源
最近更新 更多