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?

10
  • 1
    Just a comment: you don't need to test the result of memset. Commented Jan 18, 2016 at 18:17
  • itoa does not procude leading zeroes. For example, with base 10 you will never get 097. Commented Jan 18, 2016 at 18:19
  • @ Ian Abbott, thanks good to know. Commented Jan 18, 2016 at 18:20
  • @Jongware so itoa won't put a leading zero but it will put a leading one? Commented Jan 18, 2016 at 18:23
  • 2
    Uh yahh. There is a big difference, isn't it? Any number can have a zillion leading zeroes and it won't change a thing. But add or leave out a one (or 4, or F when working in hex) and it's value changes. Commented Jan 18, 2016 at 18:26

3 Answers 3

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';
}
Sign up to request clarification or add additional context in comments.

1 Comment

neither of these crash with Address sanitizer on, it was one of your edits that was crashing. Both of these examples work fine, thanks.
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;
}

Comments

-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.

3 Comments

Why are you returning char strOutput[10]; from a function that returns just a char?
Heh, good point - that should return a char * - I stand corrected, cheers.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.