Reputation: 80
I decided to write a binary converter, the code is small and simple , it takes an integer and is supposed to output a char* with the resulting binary string.
The issue here seems to be that the last sprintf always seems to double the last prepended character.
For example if the answer is meant to be 1001001 it will print 11001001 or if it is supposed to be -10 it prints --10, the latter being particularly peculiar as that one isn't even in a loop.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
void bin_string( char** buffer ,int num ){
bool neg = false;
if ( num < 0 ){
neg = true;
num = ~num+1;
}
if( num == 0 )
sprintf( *buffer, "%d", 0 );
while( num > 0 ){
int rem = num%2;
sprintf( *buffer, "%d%s", rem, *buffer );
printf("iteration: %s rem: %d\n", *buffer, rem );
num = num/2;
}
if( neg )
sprintf( *buffer, "-%s", *buffer );
}
int main( int argc, char** argv ){
char* a = malloc( sizeof(char)*64 );
bin_string( &a, 73 );
printf("Result %s\n",a ); /* output is 11001001 but should be 1001001*/
return 0;
}
Upvotes: 1
Views: 793
Reputation:
The answer is that you're invoking undefined behavior when you're sprintf()
ing *buffer
to itself. What you should do instead is something like:
void bit_string(char *buf, int n)
{
int nbits = sizeof(n) * CHAR_BIT;
int i;
for (i = 0; i < nbits; i++) {
buf[i] = '0' + ((n >> (nbits - i - 1)) & 1);
}
buf[nbits] = 0;
}
(Yes, I've also taken care of efficiency, readability and portability for you - you're welcome.)
Upvotes: 2
Reputation: 754160
The declaration of sprintf()
in C99 and beyond is:
int sprintf(char *restrict s, const char *restrict format, ...);
You are violating the restrict
part of that declaration. You are using, for example:
sprintf(*buffer, "-%s", *buffer);
This is trying to modify the buffer in situ, and is undefined behaviour. You're lucky you're getting such nearly sane results — or maybe unlucky. You can't use the target buffer in the trailing arguments to the call to sprintf()
.
Upvotes: 5
Reputation: 13890
I suppose sprintf is just not smart enough to insert buffer into itself. You probably need to have two buffers and swap them.
Upvotes: 2