Бинарные маски и биты манипуляции в Си - PullRequest
0 голосов
/ 28 мая 2018

У меня есть задание, и я понятия не имею, что я должен делать.Вот задача:

Напишите следующую функцию: char * encodingToShortString (char * dig_str);

Функция должна создать и вернуть новую строку short_dig_str .Каждый байт в short_dig_str будет состоять из двух соответствующих битовых квартетов для двух последовательных символов dig_str .Для dig_str с длиной n (ДЛИНА, а не размер) длина short_dig_str будет n / 2 для четного n и n / 2 + 1 для нечетного n.Для нечетного n первый квартет в short_dig_str не соответствует ни одной цифре dig_str , и все его биты являются нулями.

Пример: Для dig_str = "1234", строка short_dig_str будет состоять из следующего целого числа: 00010010 00110100

Для dig_str = "51234", строка short_dig_str будет состоять из следующего целого числа: 00000101 00010010 00110100

(слева направо, старшее значащее, MSB, к младшему значащему младшему биту).

Требуемое пространство памяти должно быть назначенов строку 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 ?Я очень смущен.

1 Ответ

0 голосов
/ 28 мая 2018

Сначала посмотрите на желаемый вывод:

Пример: для 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 char или uint8_t и т. Д.чем char но ваша подпись определена как есть.

Имя codingToShortString вводит в заблуждение, поскольку не создается строка (и нет 0-терминации).

Плохие имена, плохиетипы ... Это не очень хорошее задание, я бы сказал ...

...