Way to scanf binary number?

Viewed 1249

I am trying to write a small bit of code where i can scan a binary digit, like 00110011, and get this into an integer as a number. So 00110011 would be 51. The code i made for this goes like this

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

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

    d = byte;

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

This however, give me an output of 48. 00000001 also gives me 48 and so does anything else. I know whats going wrong, it sees the string of zeros and ones as a single 0 and since its character is 0x30, or 0d48, it outputs 48. I wont to know if there is a way to get around this adn scan this in as the binary equivelent.

2 Answers

Your code does not work at all:

  • you scan up to 8 characters plus a null terminator, passing the address of a single byte variable: this has undefined behavior.
  • d = byte does not perform any conversion. the character '0' was read into byte and its ASCII value is stored into d, namely 48 as output by your program.

Furthermore, there is no standard conversion specifier for binary encoding in scanf(). Reading a string is a good approach, but you should pass a larger buffer and use a loop to convert to binary:

#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;
}

You can also use strtoul() to convert a number expressed as a string of binary digits (or in any other base up to 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;
}

Note however that the behavior of strtoul() will differ from the first code: strtoul() will return ULONG_MAX on overflow, whereas the first example would just compute the low order bits of the binary string.

I found this simple function that should be easy to understand and it does the trick. Its a algorithm that follows how you would naturally do it in real life with a pen and paper however you're gonna need -lm when you compile it(the gcc command) to include the math library, however you can get around the pow() and include problems if you just do a for loop.

#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;
}
Related