Чтение персонажей на уровне немного - PullRequest
4 голосов
/ 02 февраля 2010

Я хотел бы иметь возможность ввести символ с клавиатуры и отобразить двоичный код для указанной клавиши, например, в формате 00000001.

Кроме того, я также хотел бы прочитать биты таким образом, который позволяет мне выводить, являются ли они истинными или ложными.

, например

01010101 = false,true,false,true,false,true,false,true

Я бы опубликовал идею о том, как я пытался сделать это сам, но я абсолютно не знаю, я все еще экспериментирую с C, и это мой первый вкус программирования на таком низком уровне.

Thankyou

Ответы [ 3 ]

4 голосов
/ 02 февраля 2010

Для настройки битов часто безопаснее использовать неподписанные типы, потому что сдвиги отрицательных значений со знаком имеют эффект, зависящий от реализации. Обычный char может быть либо подписанным, либо неподписанным (традиционно он не подписан на платформах MacIntosh, но подписан на ПК). Следовательно, сначала приведите вашего персонажа к типу unsigned char.

Тогда ваши друзья - это побитовые логические операторы (&, |, ^ и ~) и операторы сдвига (<< и >>). Например, если ваш символ находится в переменной x, то для получения 5-го бита вы просто используете: ((x >> 5) & 1). Операторы сдвига перемещают значение вправо, отбрасывая пять младших битов и перемещая интересующий вас бит в «самую низкую позицию» (она же «крайний правый»). Битовое И с 1 просто устанавливает все остальные биты на 0, поэтому результирующее значение равно 0 или 1, что является вашим битом. Обратите внимание, что я нумерую биты от значащего слева (крайнего справа) до старшего значащего (крайнего слева) и начинаю с нуля, а не с единицы.

Если вы предполагаете, что ваши символы 8-битные, вы можете написать свой код как:

unsigned char x = (unsigned char)your_character;
int i;

for (i = 7; i >= 0; i --) {
    if (i != 7)
        printf(",");
    printf("%s", ((x >> i) & 1) ? "true" : "false");
}

Вы можете заметить, что, поскольку я нумерую биты справа налево, но вы хотите выводить слева направо, индекс цикла должен уменьшаться.

Обратите внимание, что согласно стандарту C unsigned char имеет не менее восьми битов, но может иметь больше (в настоящее время только несколько встроенных DSP имеют символы, которые не являются 8-битными). Для большей безопасности добавьте это в начале кода (как объявление верхнего уровня):

#include <limits.h>
#if CHAR_BIT != 8
#error I need 8-bit bytes!
#endif

Это предотвратит успешную компиляцию, если целевая система окажется одной из этих специальных встроенных DSP. Как примечание к примечанию, термин «байт» в стандарте C означает «элементарный блок памяти, который соответствует unsigned char», так что, на языке C, байт может иметь более восьми бит (байт не всегда октет). Это традиционный источник путаницы.

4 голосов
/ 02 февраля 2010

Это, вероятно, не самый безопасный способ - без проверки здравомыслия / размера / типа - но он все равно должен работать.

unsigned char myBools[8];
char myChar;  

// get your character - this is not safe and you should
// use a better method to obtain input...
// cin >> myChar; <- C++
scanf("%c", &myChar);

// binary AND against each bit in the char and then
// cast the result. anything > 0 should resolve to 'true'
// and == 0 to 'false', but you could add a '> 1' check to be sure.
for(int i = 0; i < 8; ++i)
{
   myBools[i] = ( (myChar & (1 << i) > 0) ? 1 : 0 );
}

Это даст вам массив неподписанных символов - либо 0, либо 1 (trueили ложь) - для персонажа.

3 голосов
/ 02 февраля 2010

Этот код C89:

/* we need this to use exit */
#include <stdlib.h>
/* we need this to use CHAR_BIT */
#include <limits.h>
/* we need this to use fgetc and printf */
#include <stdio.h>

int main() {
    /* Declare everything we need */
    int input, index;
    unsigned int mask;
    char inputchar;

    /* an array to store integers telling us the values of the individual bits.
       There are (almost) always 8 bits in a char, but it doesn't hurt to get into
       good habits early, and in C, the sizes of the basic types are different
       on different platforms. CHAR_BIT tells us the number of bits in a byte. 
     */
    int bits[CHAR_BIT];

    /* the simplest way to read a single character is fgetc, but note that
       the user will probably have to press "return", since input is generally 
       buffered */
    input = fgetc(stdin);
    printf("%d\n", input);

    /* Check for errors. In C, we must always check for errors */
    if (input == EOF) {
        printf("No character read\n");
        exit(1);
    }

    /* convert the value read from type int to type char. Not strictly needed,
       we can examine the bits of an int or a char, but here's how it's done. 
     */
    inputchar = input;

    /* the most common way to examine individual bits in a value is to use a 
       "mask" - in this case we have just 1 bit set, the most significant bit
       of a char. */
    mask = 1 << (CHAR_BIT - 1);

    /* this is a loop, index takes each value from 0 to CHAR_BIT-1 in turn,
       and we will read the bits from most significant to least significant. */
    for (index = 0; index < CHAR_BIT; ++index) {
        /* the bitwise-and operator & is how we use the mask.
           "inputchar & mask" will be 0 if the bit corresponding to the mask
           is 0, and non-zero if the bit is 1. ?: is the ternary conditional
           operator, and in C when you use an integer value in a boolean context,
           non-zero values are true. So we're converting any non-zero value to 1. 
         */
        bits[index] = (inputchar & mask) ? 1 : 0;

        /* output what we've done */
        printf("index %d, value %u\n", index, inputchar & mask);

        /* we need a new mask for the next bit */
        mask = mask >> 1;
    }

    /* output each bit as 0 or 1 */
    for (index = 0; index < CHAR_BIT; ++index) {
        printf("%d", bits[index]);
    }
    printf("\n");

    /* output each bit as "true" or "false" */
    for (index = 0; index < CHAR_BIT; ++index) {
        printf(bits[index] ? "true" : "false");
        /* fiddly part - we want a comma between each bit, but not at the end */
        if (index != CHAR_BIT - 1) printf(",");
    }
    printf("\n");
    return 0;
}

Вам не обязательно нужны три цикла - вы можете объединить их вместе, если хотите, и если вы выполняете только один из двух видов вывода,тогда вам не понадобится массив, вы можете просто использовать каждое битовое значение, маскируя его.Но я думаю, что это держит вещи отдельно и, надеюсь, легче понять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...