C语言中的带奇偶校验位

C语言中的带奇偶校验位,c,C,假设我有一个比特流,8比特的数据后跟2个奇偶校验位(模式重复) 示例(x为奇偶校验位): 0001 0001 xx00 0100 01xx 0001 0001 xx00 应该成为 0001 0001 0001 0001 0001 0001 0001 我觉得这应该很容易,我只是想了想,但是如何剥离这些奇偶校验位呢?这里的棘手之处是C不允许您轻松处理位,只允许处理字节。我假设您的char包含8位(检查limits.h中的char\u-BIT)——几乎所有现代系统都是这样。8和10的最小公倍数是40,

假设我有一个比特流,8比特的数据后跟2个奇偶校验位(模式重复)

示例(x为奇偶校验位):

0001 0001 xx00 0100 01xx 0001 0001 xx00

应该成为

0001 0001 0001 0001 0001 0001 0001


我觉得这应该很容易,我只是想了想,但是如何剥离这些奇偶校验位呢?

这里的棘手之处是C不允许您轻松处理位,只允许处理字节。我假设您的
char
包含8位(检查
limits.h
中的
char\u-BIT
)——几乎所有现代系统都是这样。8和10的最小公倍数是40,因此您希望在至少40位的缓冲区中工作,这样您就可以作为一个整体进行整数运算——实际上,这意味着64位类型。所以这里有一种方法,从stdin读取数据,然后向stdout写入数据。处理长度不是40位倍数的流是一项练习

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

int main(void)
{
    int c;
    uint_least64_t buffer;

    for (;;)
    {
       buffer = 0;
       /* read in 4 10-bit units = 5 8-bit units */
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);

       /* write out the non-parity bits */
       putchar((buffer & 0xFF00000000ULL) >> 32);
       putchar((buffer & 0x003FC00000ULL) >> 22);
       putchar((buffer & 0x00000FF000ULL) >> 12);
       putchar((buffer & 0x00000003FCULL) >>  2);
    }
    /* deal with incomplete block here */
    return 0;
}
#包括
#包括
内部主(空)
{
INTC;
uint_最小64_t缓冲器;
对于(;;)
{
缓冲区=0;
/*读入4个10位单位=5个8位单位*/
c=getchar();如果(c==EOF)中断;
缓冲区=((缓冲区>12);
putchar((缓冲区&0x00000003FCULL)>>2);
}
/*在这里处理不完整的块*/
返回0;
}

…如果你真的想变得聪明,你可以在扔掉这些奇偶校验位之前检查它们,尽管那时你必须想出一些有建设性的事情来做(不是如果)校验和失败。

我会在C中定义一个位域结构,然后使用它来“框定”数据缓冲区,只提取有用的位。类似这样:

struct tframe {
     unsigned data: 8;
     unsigned control: 2;
}

struct tframe * frames = &buf;

/* Iterate and write 'data' field to wherever */
...

您正在处理自己的数据,因此代码的可移植性不会成为问题。

您的数据是如何存储的?@声子数据被读入缓冲区,数据的长度是已知的。达夫的设备是否适用于处理不完整的数据块?@josec,请不要在生产代码中使用类似的任何东西。@josec,除卡尔的警告外,我我看不出这样的结构会有什么帮助。一个常规的switch语句,对读取的8字节单元计数进行键控,然后使用fall-through就可以了。达夫的设备,以其原始形式,在这里不适用,因为您要处理的是末尾的短读取,而不是开头的不对齐。跳转到a序列的中间c控制逻辑(可能将
break
s替换为
goto
s)可能是可用的,但我没有立即看到如何防止它以错误的顺序发出不完整的块(后进先出而不是先进先出)。我也有同样的问题,但在32位机器上。我有8个数据位,后跟1个奇偶校验位,模式重复,就像OP的问题一样。除了你提到的可移植性问题之外,这种使用位字段的尝试甚至不起作用-你仍然只能将它指向字节边界。对象不能有分数大小。如果扩展为seq,它会起作用四个“数据”+“控制”的影响项目,所以整个是一个8位字节的整数。模结构打包问题,如果你问我的话,这本身就是不使用这种技术的原因。当然,如果你这样做,它不会让你摆脱短读问题。是的,我认为字节边界可能是个问题,但有一段时间没有做过C!OP没有提到a任何关于数据缓冲区大小或存储类型的事情,所以我假设他知道不管怎样,他都会有短读问题(最后是0位/字节填充?)。