【问题标题】:Printing char even parity打印字符偶校验
【发布时间】:2012-03-09 23:37:04
【问题描述】:

这可能是一个愚蠢的问题,但我似乎无法弄清楚。

我编写了一个程序,它将一个字符作为输入,输出字符及其十六进制值,然后检查偶校验并将奇偶校验位设置为 1,然后再次输出“新”字符及其十六进制值。然而,使用 printf 和 %c 似乎不是要走的路,我不明白为什么或如何解决它,所以如果有人能解释为什么不这样做以及我应该做什么,我将非常感激。哦,请随意评论我正在学习的代码,所以批评总是好的:)

int checkParity(unsigned char myChar); //returns 0 if even 1 if odd

int main()  {
  int i;
  unsigned char input;

  printf("Enter char: ");
  scanf("%c", &input);

  /* print unchanged char and hex with */
  printf("c7: %c ", input);
  printf("hex: %x \n", input);

  /*if parity is odd*/
  if(checkParity(input)){
    /*change to even*/
    input = (input|0x80);
  }

  /* print char and hex even parity */
  printf("c8: %c ", input);
  printf("hex: %x \n", input);  

  return 0;
}

int checkParity(unsigned char myChar){
  int i;
  int parity = 0;

  while(myChar){    //while myChar != 0
    parity += (myChar&1);   //add result of myChar AND 1 to parity
    myChar = myChar>>1;     //shift bits left by 1
  }
  //printf("parity equals: %d\n", parity);
  if(parity%2){ // if odd parity
    return 1;
  }
  else { //even parity
    return 0;
  }
}

【问题讨论】:

  • 输出是什么,你期望它是什么?
  • 添加奇偶校验位后,我只想打印输入的字符,例如“L”后跟新的十六进制值。现在它打印出一个看起来很奇怪的正方形而不是 L。
  • 除了 >> 是右移而不是左移这一事实之外,请尝试将您的问题集中在不工作的部分代码上。例如,我不知道你是否检查校验函数的行为
  • 那是因为它不再是“L” :-) 奇偶校验位恰好是最高有效位,它被视为数据。所以你实际上是在字符的十六进制代码中添加 128。搜索“扩展 ASCII 表”以找出新字符是什么。如果要打印原始字符,可以将其复制到另一个变量中并打印。
  • 哎呀谢谢没注意到我写的左边!好吧,我检查了 checkParity 函数几次,它似乎。就像我提到的那样,不起作用的部分是使用 %c 打印一个奇偶校验位设置为 1 的字符。我们的讲师提到它不起作用,但我不知道为什么。

标签: c


【解决方案1】:

什么是奇偶校验位?

奇偶校验位是一种简单的错误检查形式,例如,当您将数据从一台机器传输到另一台机器时。如果两台机器就偶校验等问题达成一致,那么接收方将知道具有偶校验的任何传入字符都是错误接收的。但是,任何类型的奇偶校验只能识别 个错误位:单个字符中的两个错误将相互抵消,得到的奇偶校验将是正确的。此外,接收方无法确定哪个位(或多个位)不正确; parity 提供错误检测,但不提供错误纠正

应如何处理收到的数据?

接收方应计算并验证每个传入字符的奇偶性。如果它检测到具有无效奇偶校验的字符,它应该以某种方式指示错误。在最好的情况下,它可能会要求发送方重新发送字符。

验证字符后,接收方必须剥离奇偶校验位,然后再将字符传递给进一步处理。这是因为,由于奇偶校验位用于错误检测,它会从数据有效负载中“丢失”。因此,启用奇偶校验将使可用数据值的数量减少一半。例如,8 位可以有 256 个可能的值之一(0 - 255)。如果使用 1 位进行奇偶校验,则只剩下 7 位用于编码数据,只剩下 128 个有效值。


由于您要求 cmets/criticism,这里是您的代码的修订、注释版本:

#include <stdio.h>

// Consider using a boolean data type, as the function returns
// "true" or "false" rather than an arbitrary integer.
int isOddParity(unsigned char myChar);


int main(void) {
  unsigned char input;

  printf("Enter char: ");
  scanf("%c", &input);

  // Force even parity by setting MSB if the parity is odd.
  unsigned char even = isOddParity(input) ? input | 0x80 : input;

  // Print the original char, original hex, and even-parity hex
  // Print hex values as 0xHH, zero-padding if necessary.  This program
  // will probably never print hex values less than 0x10, but zero-padding
  // is good practice.
  printf("orig char: %c\n", input);
  printf("orig  hex: 0x%02x\n", input);
  printf("even  hex: 0x%02x\n", even);
  return 0;
}

// Calculate the parity of myChar.
// Returns 1 if odd, 0 if even.
int isOddParity(unsigned char myChar) {
  int parity = 0;

  // Clear the parity bit from myChar, then calculate the parity of
  // the remaining bits, starting with the rightmost, by toggling
  // the parity for each '1' bit.
  for (myChar &= ~0x80;  myChar != 0;  myChar >>= 1) {
    parity ^= (myChar & 1);   // Toggle parity on each '1' bit.
  }
  return parity;
}

【讨论】:

  • 感谢您的详细解释,这真的很有帮助。
猜你喜欢
  • 2015-06-29
  • 2019-10-09
  • 1970-01-01
  • 2013-06-25
  • 1970-01-01
  • 2015-06-05
  • 2014-03-02
  • 2013-04-21
  • 2019-05-10
相关资源
最近更新 更多