将 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);
玩得很开心:-)
我有一个整数值从 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);
玩得很开心:-)