添加二进制字符串时结果不正确

时间:2019-01-08 19:08:06

标签: c

添加两个二进制字符串“ 11” +“ 11”时,得到的结果不正确。我期望的是“ 110”,但是我得到的答案是“ 010”。如果进位仍然为1,我确实添加了一个特例。

char *addBinary(char *str1, char *str2)
{
    int len1 = strlen(str1); //assume both string lengths are same
    char *res = (char *)malloc((len1 + 1) * sizeof(char));
    int i, a, b;
    int carry = 0;
    char result;
    for (i = len1 - 1; i >= 0; i--)
    {
        a = str1[i] - '0';
        b = str2[i] - '0';
        carry = a + b + carry;
        printf("%d %d %d \n", a, b, carry % 2);
        result = carry % 2 + '0'; //convert to character
        carry = carry / 2;
        str1[i] = result; //use the existing string for the result
    }
    if (carry == 0)
    { //if there is no carry just use the existing string and return
        printf("Final without carry %s \n", str1);
        return str1;
    }
    else
    { //there was a carry, so put 1 in the 0th location and copy the string
        res[0] = 1;
        memcpy(res + 1, str1, sizeof(char) * len1);
        printf("Final %s %s %d\n", res, str1,strlen(res));
        return res;
    }
}

int main()
{
    char bin_str1[] = "11";
    char bin_str2[] = "11";
    printf("%s \n",addBinary(bin_str1, bin_str2));
    return 0;
}

2 个答案:

答案 0 :(得分:3)

您有两个主要问题:

首先,当您为res分配空间时:

char *res = (char *)malloc((len1 + 1) * sizeof(char));

您需要为len1+2分配空间(进行和终止NUL),否则您的memcpy将超出范围(您应该复制len1+1元素,否则不保证resNUL终止)。另外请注意,在返回str1的情况下,内存已泄漏。

res的第一个字符设置为可打印字符时会发生第二个问题:

res[0] = 1;

您应该将其设置为'1'

答案 1 :(得分:1)

还要考虑的另一件事是,如果您有这样的事情:

char bin_str1[] = "10";
char bin_str2[] = "11";

您的addBinary()函数不会返回res,而是返回str1

现在这才是重点,如果您为函数分配一个指针,以便可以将内存释放回系统,则将有一个无效的free()

一种方法可能是这样的:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>

char *addBinary(char *str1, char *str2);

int main( void )
{
    char bin_str1[] = "11";
    char bin_str2[] = "11";
    char *ptr = addBinary( bin_str1, bin_str2 );

    if ( ptr )
    {
        printf("%s \n",ptr );
        free( ptr );
    }
}

char *addBinary(char *str1, char *str2)
{
    char *res = calloc( strlen( str1 ) + strlen( str2 ), sizeof( *res ) );
    int a, b, carry = 0;
    size_t i = strlen( str1 ) - 1;

    while ( i > 0 )
    {
        a = str1[i] - '0';
        b = str2[i] - '0';
        carry += a + b;
        printf("%d %d %d \n", a, b,( carry % 2));
        str1[i] = (char)( carry % 2 + '0'); ///convert to character
        carry = carry / 2;
        i--;
    }
    if ( carry == 0 )
    { ///if there is no carry RETURN NULL
        printf("Final without carry %s \n", str1);
        free( res );
        return NULL;
    }
    else
    { //there was a carry, so put 1 in the 0th location and copy the string
        res[0] = '1';
        strcat( res, str1 );
        printf("Final %s %s %zu\n", res, str1,strlen( res ));
        return res;
    }
}

或者,您可以放下malloc并像这样使用它:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>

int addBinary( char *dest, char *const str1, const char *const str2);

int main( void )
{
    char bin_str1[] = "11";
    char bin_str2[] = "11";
    char dest[256] = { 0 };

    if ( addBinary( dest, bin_str1, bin_str2 ) )
    {
        printf("Dest = %s\n", dest );
    }
}

int addBinary( char *dest, char *const str1, const char *const str2)
{
    int a, b, carry = 0;
    size_t i = strlen( str1 ) - 1;

    while ( i > 0 )
    {
        a = str1[i] - '0';
        b = str2[i] - '0';
        carry += a + b;
        str1[i] = (char)( carry % 2 + '0'); ///convert to character
        carry = carry / 2;
        i--;
    }
    if ( carry )
    {
        dest[0] = '1';
        strcat( dest, str1 );
        return 1;
    }
    return 0;
}

我对您的代码进行了一些更改,以减少代码的使用量。