将 9 位值的流作为字节写入 C 中的文件

Writing a stream of 9 bit values as bytes to a file in C

我有一个整数值从 0-511(最多 9 位)的数组。我正在尝试将其写入 fwrite.

的文件

例如,数组:

[257, 258, 259]
Which is 100000001, 100000010, 100000011

I am trying to write
100000001100000010100000011 + extra padding of 0s to the file 

但是由于 fwrite 一次只能写入 1 个字节,所以我不确定该怎么做。我是按位运算的新手,不知道如何分离出各个字节。

你需要一点缓冲。

由于你当时写的是8位,所以必须 具有至少可以容纳至少 9+7 位的数据类型。 uint16_t 可以, 但我建议使用至少与本机 int 一样大的尺寸。确保使用无符号类型以避免移位问题。

uint32_t bitBuffer = 0;  // Our temporary bit storage
uint32_t count = 0;      // Number of bits in buffer

假设我们有单个数据:

uint32_t data9b = 257;  // 1 0000 0001

向缓冲区添加位很简单;只需在缓冲区末尾移动位, 并结合 OR.

bitBuffer |= (data9b << count); // At first iteration, shift does nothing
count += 9;                     // Update counter

添加9位后,我们可以将8位刷入文件。

while(count >= 8) {
    writeToFile(bitBuffer & 0xFF);  // Mask out lowest bits with AND
    bitBuffer >>= 8;                // Remove written bits
    count -= 8;                     // Fix counter
}

在每个循环之后,缓冲区中还剩下 0 - 7 位。在所有数据的最后,如果以非8位的倍数结束,只需将bitBuffer的剩余内容写入文件即可。

if(count > 0)
    writeToFile(bitBuffer);

好的,它也是使用移位,oring(也可以使用 *、'+'、%/)但是移位更合适/可读,我。

// Your data, n is the number of 9-bits values
uint16_t dat[] = { 257, 258, 259 };
int i,n = sizeof(dat)/sizeof(*dat);

// out file
FILE *fp = fopen("f8.bin","w");

uint16_t one = 0;
int shift = 0;
uint8_t b;

// main loop
for(i=0 ; i<n ; i++) {
    b = (dat[i] << shift) | one; // one is remainder from previous value
    one = dat[i]>>(8-shift);     // Move the remaining MSb to the right
    shift = (shift+9) % 8;       // next shift
    fwrite(&b, 1, 1, fp);        // write our b byte
}
// remainder, always have a remainder
fwrite(&one, 1, 1, fp);
fclose(fp);

玩得很开心:-)