0

I'm trying to convert an ascii string to a binary string in C. I found this example Converting Ascii to binary in C but I rather not use a recursive function. I tried to write an iterative function as opposed to a recursive function, but the binary string is missing the leading digit. I'm using itoa to convert the string, however itoa is a non standard function so I used the implementation from What is the proper way of implementing a good "itoa()" function? , the one provided by Minh Nguyen.

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int32_t ascii_to_binary(char *input, char **out, uint64_t len)
{
    uint32_t i;
    uint32_t str_len = len * 8;

    if(len == 0)
    {
        printf("Length argument is zero\n");
        return (-1);
    }

    (*out) = malloc(str_len + 1);
    if((*out) == NULL)
    {
        printf("Can't allocate binary string: %s\n", strerror(errno));
        return (-1);
    }

    if(memset((*out), 0, (str_len)) == NULL)
    {
        printf("Can't initialize memory to zero: %s\n", strerror(errno));
        return (-1);
    }

    for(i = 0; i < len; i++)
        itoa((int32_t)input[i], &(*out)[(i * 8)], 2);

    (*out)[str_len] = '\0';

    return (str_len);
}

int main(void)
{
    int32_t rtrn = 0;
    char *buffer = NULL;

    rtrn = ascii_to_binary("a", &buffer, 1);
    if(rtrn < 0)
    {
        printf("Can't convert string\n");
        return (-1);
    }

    printf("str: %s\n", buffer);

    return (0);
}

I get 1100001 for ascii character a, but I should get 01100001, so how do I convert the ascii string to the whole binary string?

Community
  • 1
  • 1
2trill2spill
  • 1,333
  • 2
  • 20
  • 41

3 Answers3

2

You could change the for loop to something like this:

for(i = 0; i < len; i++) {
    unsigned char ch = input[i];
    char *o = *out + 8 * i;
    int b;

    for (b = 7; b >= 0; b--)
        *o++ = (ch & (1 << b)) ? '1' : '0';
}

or similar:

for(i = 0; i < len; i++) {
    unsigned char ch = input[i];
    char *o = &(*out)[8 * i];
    unsigned char b;

    for (b = 0x80; b; b >>= 1)
        *o++ = ch & b ? '1' : '0';
}
Ian Abbott
  • 15,083
  • 19
  • 33
  • neither of these crash with Address sanitizer on, it was one of your edits that was crashing. Both of these examples work fine, thanks. – 2trill2spill Jan 18 '16 at 18:52
0

This program gets and integer ( which contains 32 bits ) and converts it to binary, Work on it to get it work for ascii strings :

#include <stdio.h>

int main()
{
  int n, c, k;

  printf("Enter an integer in decimal number system\n");
  scanf("%d", &n);

  printf("%d in binary number system is:\n", n);

  for (c = 31; c >= 0; c--)
  {
    k = n >> c;

    if (k & 1)
      printf("1");
    else
      printf("0");
  }

  printf("\n");

  return 0;
}
-1

Best just write a simple function to do this using bitwise operators...

#define ON_BIT = 0x01

char *strToBin(char c) {
    static  char    strOutput[10];
    int     bit;

    /*Shifting bits to the right, but don't want the output to be in reverse
     * so indexing bytes with this...
     */
    int     byte;

    /* Add a nul at byte 9 to terminate. */
    strOutput[8] = '\0';

    for (bit = 0, byte = 7; bit < 8; bit++, byte--) {
        /* Shifting the bits in c to the right, each time and'ing it with
         * 0x01 (00000001).
         */
        if ((c >> bit) & BIT_ON)
            /* We know this is a 1. */
            strOutput[byte] = '1';
        else
            strOutput[byte] = '0';
    }

    return strOutput;
}

Something like that should work, there's loads of ways you can do it. Hope this helps.

Nunchy
  • 948
  • 5
  • 11
  • Why are you returning `char strOutput[10];` from a function that returns just a char? – 2trill2spill Jan 18 '16 at 18:36
  • Heh, good point - that should return a char * - I stand corrected, cheers. – Nunchy Jan 18 '16 at 18:39
  • The edited function looks fine now, although it is not reentrant, and old results are overwritten every time it is called, unless the caller copies them elsewhere. – Ian Abbott Jun 08 '16 at 11:51