преобразование двоичного кода в соответствующий символ ASCII - PullRequest
0 голосов
/ 05 октября 2019

Итак, я пытаюсь создать программу, в которой пользователь вводит 12-битную последовательность двоичного кода Хэмминга, например «100010010001», и она должна распечатать соответствующий ему символ ASCII, который в данном случае равен «A».

Я пытаюсь заставить мою программу игнорировать 4 бита четности, которые расположены в _ _ 0 _ 1 0 0 _ 0 0 0 1, и сдвигать остальные 8 бит, чтобы они были вместе. В операторе else я попытался преобразовать оставшиеся 8 бит в символ. Однако, когда я пытаюсь запустить программу, происходит сбой программы после того, как я ввожу свою двоичную последовательность и нажимаю ввод. Это часть программы, с которой я борюсь, и мне было интересно, может ли кто-нибудь помочь мне или дать мне подсказки о том, что я делаю неправильно?

char charToBin(char usersInput[]) {
    char c = " ";
    for (int i = 12; i >= 0; i--) {
        if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
            usersInput[i] = usersInput[i + 1];
        }else{
            c = strtol(usersInput[i], (char **)NULL, 2);
        }
    }
    return c;
}

Ответы [ 4 ]

0 голосов
/ 05 октября 2019

В качестве альтернативы вы можете использовать битовые операции. Что-то вроде:

char charToBin(char usersInput[]) {
    unsigned c = strtol(usersInput, NULL, 2);
    unsigned part1 = c & 0xFu;
    unsigned part2 = c >> 1u & 0x70u;
    unsigned part3 = c >> 2u & 0x80u;
    return (char) (part1 | part2 | part3);
}

Что даст при вашем вводе

char userInput[] = "100010010001";
char ch = charToBin(userInput);
printf("result: %c(%d)\n", ch, ch);

следующий вывод на консоли:

result: A(65)
0 голосов
/ 05 октября 2019

В вашей программе есть две ошибки компиляции:

  1. Вы не можете присвоить строку символу (c = "");
  2. Вызов strtol принимает строку, а не символ

После исправления ошибки компиляции необходимо внести два исправления в логику: 1. Выполните фильтрацию входной строки слева направо, чтобы избежать копирования позиций с 12 по 11, с 11 по 10, что приведет кв дублировании последних позиций. Дополнительный счетчик необходим, чтобы помочь с уплотнением. 2. Выполните команду strtol один раз, после того как вход полностью уплотнен.

char charToBin(char usersInput[]) {
    char j = 0 ;
    // Copy relevant input positions, INCLUDING terminating NUL byte at position 12.
    for (int i = 0; i <= 12 ; i++) {
        if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
                continue ;
        } ;
        usersInput[j] = usersInput[i] ;
        j++ ;
    } ;
    char c = strtol(usersInput, (char **)NULL, 2);
    return c;
}

0 голосов
/ 05 октября 2019

Для вашего кода вы не можете использовать "strtol" без изюминки. Массив char, который вы передаете "strtol", может не заканчиваться на "\ 0". Кроме того, не имеет значения, что вы делаете, ваш массив всегда будет иметь 12 индексов, если вы не скопируете «\ 0» в индекс 9, чтобы «strtol» знал, что это конец ввода.

Кроме того, иногда петли не самые лучшие. Для вашего случая вы уже знаете, с какими индексами вы работаете. Нет смысла использовать цикл. Тем не менее, я написал два метода и включил тестовый код в качестве примера ниже.

#include <stdio.h>

/*
 * This function generate a hammer binary digit string for testing.
 * It does not care about the validity of the hammer bit.
 * The array that is passed to this function should be the length of 12.
 */

void generateChar(int value, char * output){
    output[0] = '0';
    output[1] = '0';
    output[3] = '0';
    output[7] = '0';
    output[2] =  (value & 0b10000000) > 0? '1' : '0';
    output[4] =  (value & 0b01000000) > 0? '1' : '0';
    output[5] =  (value & 0b00100000) > 0? '1' : '0';
    output[6] =  (value & 0b00010000) > 0? '1' : '0';
    output[8] =  (value & 0b00001000) > 0? '1' : '0';
    output[9] =  (value & 0b00000100) > 0? '1' : '0';
    output[10] = (value & 0b00000010) > 0? '1' : '0';
    output[11] = (value & 0b00000001) > 0? '1' : '0';   
}

/* 
 * First method.
 *
 */
char charToBin(char usersInput[]) {
    char c = 0;
    c = usersInput[2] == '1'?  c | 0b10000000 : c;
    c = usersInput[4] == '1'?  c | 0b01000000 : c;
    c = usersInput[5] == '1'?  c | 0b00100000 : c;
    c = usersInput[6] == '1'?  c | 0b00010000 : c;
    c = usersInput[8] == '1'?  c | 0b00001000 : c;
    c = usersInput[9] == '1'?  c | 0b00000100 : c;
    c = usersInput[10] == '1'? c | 0b00000010 : c;
    c = usersInput[11] == '1'? c | 0b00000001 : c;

    return c;
}

/*
 * Second method.
 */
char charToBin2(char usersInput[]) {
    char temp[9];
    int pos = 0;
    temp[8] = '\0'; // Protect from overflow.

    for ( int i = 2; i < 12; i++ ){
        if ( i == 3 || i == 7 ) continue;
        temp[pos] = usersInput[i];
        pos++;
    }

    return (char) strtol(temp, (char **)NULL, 2);
}

int main(){
    char a[] = "100010010001";
    char t[12];
    int b;

    // Test for method 1
    for ( int i = 0; i < 256; i++ ){
        generateChar(i, t);
        b = charToBin(t);
        printf("%d ", (unsigned char) b );
    }

    printf("\n\n");

    // Test for method 2
    for ( int i = 0; i < 256; i++ ){
        generateChar(i, t);
        b = charToBin2(t);
        printf("%d ", (unsigned char) b );
    }

    return 0;
}
0 голосов
/ 05 октября 2019
if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
            usersInput[i] = usersInput[i + 1];
        }else{

Здесь ваше if (условие), фигурная скобка после этого не нужна.

if((i == 0) || (i == 1) || (i == 3) || (i == 7))
            usersInput[i] = usersInput[i + 1];
        else{

, что бы исправить немного, возможно

...