Я пытаюсь написать небольшой фрагмент кода, в котором я могу сканировать двоичную цифру, например 00110011, и преобразовать ее в целое число в виде числа. Так что 00110011 будет 51. Код, который я сделал для этого, выглядит следующим образом

int main()
{
    unsigned char byte;
    int d;

    scanf("%8s", &byte);

    d = byte;

    printf("%d,%c",d, byte);
    return 0;
}

Однако это дает мне результат 48. 00000001 также дает мне 48, как и все остальное. Я знаю, что идет не так, он видит строку нулей и единиц как один 0 и, поскольку его символ - 0x30 или 0d48, он выводит 48. Я не хочу знать, есть ли способ обойти это и сканировать это как двоичный эквивалент.

2
Bas de Wildt 17 Сен 2021 в 21:40

2 ответа

Лучший ответ

Ваш код вообще не работает:

  • вы сканируете до 8 символов плюс нулевой терминатор, передавая адрес однобайтовой переменной. Это имеет неопределенное поведение.
  • d = byte не выполняет никаких преобразований. символ '0' был считан в byte, и его значение ASCII сохраняется в d, а именно 48 как вывод вашей программы.

Кроме того, нет стандартного спецификатора преобразования для двоичного кодирования в scanf(). Чтение строки - хороший подход, но вы должны передать больший буфер и использовать цикл для преобразования в двоичный формат:

#include <ctype.h>
#include <stdio.h>

int main() {
    char buf[100];

    /* read a sequence of at most 99 binary digits into buf */
    if (scanf(" %99[01]", buf) == 1) {
        unsigned int d = 0;
        /* convert the binary digits one at a time into integer d */
        for (int i = 0; buf[i]; i++) {
            d = (d << 1) | (buf[i] - '0');
        }
        /* print value as a number */
        printf("%s -> %d\n", buf, d);
        if (d == (unsigned char)d && isprint(d)) {
            /* print value as a character if printable */
            printf("%s -> %c\n", buf, d);
        }
    }
    return 0;
}

Вы также можете использовать strtoul() для преобразования числа, выраженного в виде строки двоичных цифр (или в любой другой системе счисления до 36):

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    char buf[100];

    /* read a sequence of at most 99 binary digits into buf */
    if (scanf(" %99[01]", buf) == 1) {
        unsigned long d = strtoul(buf, NULL, 2);
        /* print value as a number */
        printf("%s -> %lu\n", buf, d);
        if (d == (unsigned char)d && isprint((unsigned char)d)) {
            /* print value as a character if printable */
            printf("%s -> %c\n", buf, (unsigned char)d);
        }
    }
    return 0;
}

Обратите внимание, однако, что поведение strtoul() будет отличаться от первого кода: strtoul() вернет ULONG_MAX при переполнении, тогда как первый пример просто вычислит младшие биты двоичной строки.

1
chqrlie 17 Сен 2021 в 19:48

Публиковать такие простые вопросы на SO - не лучшая идея, так как вы можете проголосовать за то, чтобы не делиться никакими усилиями или не выкидывать свою домашнюю работу здесь, и если да, то вы получите огромное количество голосов. Ознакомьтесь с кодексом поведения и на форумах, чтобы узнать, как задать хороший вопрос, здесь

В любом случае я нашел эту простую функцию, которая должна быть простой для понимания, и она делает свое дело. Это простая функция, которая соответствует тому, как вы, естественно, делаете это в реальной жизни с ручкой и бумагой, однако вам понадобится -lm, когда вы скомпилируете ее (команда gcc), чтобы включить математическую библиотеку, однако вы можете обойти силу () и включите проблемы, если вы просто выполните цикл for.

#include <stdio.h>
#include <math.h>
int todecimal(long bno){
   int dno = 0, i = 0, rem;
   while (bno != 0) {
      rem = bno % 10;
      bno /= 10;
      dno += rem * pow(2, i);
      ++i;
   }
   return dno;
}
0
Imeguras 17 Сен 2021 в 19:03