7

I am trying to convert a character to its binary representation (so character --> ascii hex --> binary).

I know to do that I need to shift and AND. However, my code is not working for some reason.

Here is what I have. *temp points to an index in a C string.

char c;
int j;
for (j = i-1; j >= ptrPos; j--) {
    char x = *temp;
    c = (x >> i) & 1;
    printf("%d\n", c);
    temp--;
}
darksky
  • 20,411
  • 61
  • 165
  • 254
  • what is `ptrPos`, what is `i`? – Hogan Oct 23 '11 at 00:18
  • It sounds like you're trying to convert a **single** char to binary, which in that case is fairly simple and means you don't need a pointer (that wouldn't make any sense), you just need to shift through the bits and check if it's 1 (AND with 1). Look at Salvatore's second snippet. – AusCBloke Oct 23 '11 at 00:33
  • Can you show us an example or two of specific inputs and outputs? – Keith Thompson Oct 23 '11 at 01:28

3 Answers3

37

We show up two functions that prints a SINGLE character to binary.

void printbinchar(char character)
{
    char output[9];
    itoa(character, output, 2);
    printf("%s\n", output);
}

printbinchar(10) will write into the console

    1010

itoa is a library function that converts a single integer value to a string with the specified base. For example... itoa(1341, output, 10) will write in output string "1341". And of course itoa(9, output, 2) will write in the output string "1001".

The next function will print into the standard output the full binary representation of a character, that is, it will print all 8 bits, also if the higher bits are zero.

void printbincharpad(char c)
{
    for (int i = 7; i >= 0; --i)
    {
        putchar( (c & (1 << i)) ? '1' : '0' );
    }
    putchar('\n');
}

printbincharpad(10) will write into the console

    00001010

Now i present a function that prints out an entire string (without last null character).

void printstringasbinary(char* s)
{
    // A small 9 characters buffer we use to perform the conversion
    char output[9];

    // Until the first character pointed by s is not a null character
    // that indicates end of string...
    while (*s)
    {
        // Convert the first character of the string to binary using itoa.
        // Characters in c are just 8 bit integers, at least, in noawdays computers.
        itoa(*s, output, 2);

        // print out our string and let's write a new line.
        puts(output);

        // we advance our string by one character,
        // If our original string was "ABC" now we are pointing at "BC".
        ++s;
    }
}

Consider however that itoa don't adds padding zeroes, so printstringasbinary("AB1") will print something like:

1000001
1000010
110001
Salvatore Previti
  • 8,956
  • 31
  • 37
  • 2
    Technically, it should be `i = CHAR_BIT - 1`. You know, for all those 9- and 11-bit processors out there. – Chris Lutz Oct 23 '11 at 00:33
  • I don't understand what you mean by `iota don't adds padding zeros`. So what's the different between using `iota` and using the shift and & method? – darksky Oct 23 '11 at 02:23
  • 1
    This is wrong. itoa takes an integer, and you're passing *s, a character. – darksky Oct 23 '11 at 02:23
  • 2
    Not an error. *s means the first character pointed by the string s. In c characters are just 8 bit integer (nowadays). – Salvatore Previti Oct 23 '11 at 02:25
  • 1
    itoa(10, output, 2) will write into output string the string "1010". – Salvatore Previti Oct 23 '11 at 02:37
  • 1
    printbincharpad(10) will write into the console the string "00001010". – Salvatore Previti Oct 23 '11 at 02:37
  • @SalvatorePreviti My problem with `itoa()` isn't the passing of a `char`, (promotion will occur, though sign extension can be a problem with high ascii). Its that `itoa` isn't part of the standard C library in the first place, and as such should be avoided if portability is desired. Your alternative is a much better fit, and much closer to standard-compliant (that hard-coded `7` in `printbincharpad` should be `CHAR_BIT-1` and `` should be included). – WhozCraig Oct 13 '14 at 23:54
5
unsigned char c;

for( int i = 7; i >= 0; i-- ) {
    printf( "%d", ( c >> i ) & 1 ? 1 : 0 );
}

printf("\n");

Explanation:

With every iteration, the most significant bit is being read from the byte by shifting it and binary comparing with 1.

For example, let's assume that input value is 128, what binary translates to 1000 0000. Shifting it by 7 will give 0000 0001, so it concludes that the most significant bit was 1. 0000 0001 & 1 = 1. That's the first bit to print in the console. Next iterations will result in 0 ... 0.

Simlandir
  • 57
  • 1
  • 3
3

Your code is very vague and not understandable, but I can provide you with an alternative.

First of all, if you want temp to go through the whole string, you can do something like this:

char *temp;
for (temp = your_string; *temp; ++temp)
    /* do something with *temp */

The term *temp as the for condition simply checks whether you have reached the end of the string or not. If you have, *temp will be '\0' (NUL) and the for ends.

Now, inside the for, you want to find the bits that compose *temp. Let's say we print the bits:

for (as above)
{
    int bit_index;
    for (bit_index = 7; bit_index >= 0; --bit_index)
    {
        int bit = *temp >> bit_index & 1;
        printf("%d", bit);
    }
    printf("\n");
}

To make it a bit more generic, that is to convert any type to bits, you can change the bit_index = 7 to bit_index = sizeof(*temp)*8-1

Shahbaz
  • 46,337
  • 19
  • 116
  • 182