【问题标题】:Binary Masks and Bits manipulation in CC中的二进制掩码和位操作
【发布时间】:2018-11-07 01:15:03
【问题描述】:

我有一个任务,我不知道我应该做什么。这是任务:

编写以下函数: char * encodingToShortString(char * dig_str);

该函数应该创建并返回一个新字符串short_dig_strshort_dig_str 中的每个字节将由 dig_str 的两个连续字符的两个对应位四重奏组成。 对于长度为 n(LENGTH,而不是大小)的 dig_strshort_dig_str 的长度对于偶数 n 为 n / 2,对于奇数 n 为 n / 2 + 1。 对于奇数 n,short_dig_str 中的第一个四重奏与 dig_str 的任何数字都不匹配,并且它的所有位都是零。

示例: 对于 dig_str = "1234",字符串 short_dig_str 将由以下整数组成: 00010010 00110100

对于 dig_str = "51234",字符串 short_dig_str 将由以下整数组成: 00000101 00010010 00110100

(从左到右,最重要的 MSB,到最不重要的 LSB)。

需要的内存空间必须准确分配给short_dig_str字符串。 可以假设有足够的内存进行分配。

我已经启动了这样的功能:

char* codingToShortString(char* dig_str)//let's imagine that dig_str[] = "12";
{
   char *short_dig_str;
   char temp;//0000 0000
   int n = strlen(dig_str);
   unsigned mask = 1<<3;//1111
   unsigned c; //bit counter
   if (n%2 == 0)
   {
     short_dig_str = malloc(((n/2)+1)*sizeof(char));
   }
   else
   {
     short_dig_str = malloc(((n/2)+2)*sizeof(char));
   }
   for (i=0; i<n; i++)
   {
     for (c=1; c<=4; c++)
      {
        temp = dig_str[i] & mask;
        temp <<= 1;
      }
   }
}

但后来我不知道该怎么办。我如何将二进制值放入 short_dig_str?我很困惑。

【问题讨论】:

  • 您应该做的称为“BCD 编码”。您可能会将其视为将“1234”转换为 {0x12, 0x34}。你不需要通过位掩码走这条路。
  • mask 不是0x1111: unsigned mask = 1&lt;&lt;3;//1111
  • 您的代码甚至无法编译。请修改并编辑您的问题。

标签: c string binary bit masking


【解决方案1】:

先看看想要的输出:

示例:对于 dig_str = "1234",字符串 short_dig_str 将由以下整数组成:00010010 00110100

对于 dig_str = "51234",字符串 short_dig_str 将由以下整数组成:00000101 00010010 00110100

“整数”表示一个(无符号)字符。如果你把结果写成十六进制值,你会得到

"1234" => 0x12, 0x34

"51234" => 0x05, 0x12, 0x34

您采用的方法过于复杂。 您不需要任何位掩码。

char* codingToShortString(char* dig_str)
{
  int n = strlen(dig_str);

  // Add 1 before dividing to "round up", add 1 for \0
  char *short_dig_str = malloc((n+1)/2 + 1);

  unsigned char digits;
  int out_pos = 0;  // Read index within input: "12345"
  int in_pos = 0;   // Write index within output: {0x01,0x23,0x34}

  // First handle odd number of digits
  // Foe even numbers no special treatment needed.
  if (n%2 != 0)
  {
    digits = dig_str[in_pos++] - '0';
    short_dig_str[out_pos++] = digit;
  }

  // Then handle remaining digits (as pairs!).
  for ( ; in_pos < n; )
  {
      digits  = (dig_str[in_pos++] -'0') << 4; // one digits in upper half ...
      digits |= dig_str[in_pos++] - '0';       // ... one digit in lower half

      // Store into result array...
      short_dig_str[out_pos++] = digits;
  }

  return short_dig_str;
}

由于返回的指针不是用作字符串,而是用作存储 2 个小数的原始字节,因此它应该是 unsigned charuint8_t 等,而不是 char,但您的签名已按原样定义。

名称 codingToShortString 具有误导性,因为没有创建字符串(也没有 0 终止符)。

糟糕的名字,糟糕的类型......我会说这不是一个很好的任务......

【讨论】:

  • 我看不懂你的代码,你能详细解释一下吗?
  • 首先,非常感谢。但由于某种原因,如果我想打印新字符串,它不会打印任何东西。更有趣的是:如果我将源字符串的长度设置为 2 和字符串“12”,则没有输出,但如果我设置长度为 4 和字符串“1234”,它会打印 4,这是错误的。为什么?主函数修改了好几次,没有任何变化。
  • 您是否看到我提到输出不是字符串?如果是,您尝试打印什么/如何打印?额外提示:'4' 的 ASCII 值是多少?
  • 非常感谢,我已经处理了这一个和两个按位运算的练习。
猜你喜欢
  • 1970-01-01
  • 2017-10-22
  • 2012-08-02
  • 1970-01-01
  • 1970-01-01
  • 2021-02-11
  • 1970-01-01
  • 2017-03-19
  • 1970-01-01
相关资源
最近更新 更多