C ++二进制到十进制和后向转换器

时间:2014-12-31 18:16:27

标签: c++ converter

我几乎解决了这个练习: 二进制到十进制和后向转换器 - "开发一个转换器,将十进制数转换为二进制数或二进制数转换为十进制数。" 因此,二进制到十进制转换器完美地工作,但另一个不是。 convertToBinary()函数返回垃圾,我不知道为什么。这是代码:

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

char* convertToBinary(int dec);
int convertToDec(const char* bin);

int main()
{
    std::cout << convertToBinary(100) << std::endl; // wtf!
    return 0;
}

char* convertToBinary(int dec)
{
    char binary[15] = "";
    int result;
    for(int i = 0; dec >= 1; dec /= 2, ++i)
    {
      result = !((dec % 2) == 0);
      binary[i] = result + 48;
    }
    for(int i = strlen(binary); strlen(binary) % 4 != 0; ++i) // add some zeros to make it look cool
      binary[i] = '0';
    for(int i = 0, j = strlen(binary)-1; i < j; ++i, --j) // reverse the array
    {
      char temp = binary[i];
      binary[i] = binary[j];
      binary[j] = temp;
    }
    std::cout << binary << std::endl; // looking good!
    return binary;
}

int convertToDec(const char* bin)
{
    int dec = 0;
    int size = strlen(bin);
    for(int i = 0; *bin; ++i, ++bin)
    {
      int ch = *bin - 48;
      dec += ch * pow(2, size - i - 1);
    }
    return dec;
}

2 个答案:

答案 0 :(得分:0)

使用c语言

char *convertToBinary(int value)
{
    char   *binary;
    size_t  length;
    size_t  i;   

    length = 8 * sizeof(value);
    binary = malloc(1 + length);
    if (binary == NULL)
        return NULL;
    for (i = 0 ; i < length ; ++i)
        binary[length - i - 1] = (value & (1 << i)) ? '1' : '0';
    binary[length] = '\0';

    return binary;
}

int binaryToDecimal(const char *binary)
{
    int    value;
    size_t length;
    size_t i;

    value  = 0;
    length = strlen(binary);

    for (i = 0 ; i < length ; i++)
        value |= (binary[i] == '1') ? (1 << (length - i - 1)) : 0;
    return value;
}

使用c ++语言

std::string convertToBinary(int value)
{
    std::string binary;
    size_t      length;

    length = 8 * sizeof(value);

    binary.resize(length);
    for (size_t i = 0 ; i < length ; ++i)
        binary[length - i - 1] = (value & (1 << i)) ? '1' : '0';
    return binary;
}

int binaryToDecimal(const std::string &binary)
{
    int    value;
    size_t length;

    value  = 0;
    length = binary.length();

    for (size_t i = 0 ; i < length ; i++)
        value |= (binary[i] == '1') ? (1 << (length - i - 1)) : 0;
    return value;
}

要从二进制转换为十进制,当然可以使用strtol

你的错误是返回一个局部变量,一个局部变量在函数返回时自动释放,因此你得到了垃圾。

答案 1 :(得分:0)

当你做这样的事情时:

char *toString(...)
{
    char res[MAX_RES];

    // fill res
    return res;
}

将数组res创建为堆栈上的本地数组。从函数返回时,此数组超出范围;指向此数组的指针不再有效,很可能指向垃圾。

如果你想使用C风格的char缓冲区,有两种方法可以解决这个问题:

在堆上分配结果。

char *toString(...)
{
    char *res = malloc(MAX_RES);

    // fill res
    return res;
}

使用malloc在堆上分配的数据在free明确发布之前有效。这种方法的优点是你可以根据自己的意愿制作字符串。回归是分配可能失败。值得注意的是,调用者现在拥有该字符串并负责free它:

char *x = toString(...);

// do stuff with x
free(x);

**传递缓冲区和最大长度**

int toString(char *res, size_t max, ...)
{
    // fill res
}

这是许多库函数使用的方法,尤其是snprintf。调用者必须提供自己的缓冲区和最大允许长度信息,以避免缓冲区溢出。此方法必须跟踪缓冲区大小并在必要时截断结果,可能保持字符串以null结尾。这些函数可以是void,但习惯上返回实际的字符串长度或-1作为错误指示符。

它被称为:

char x[200];

toString(x, sizeof(x), ...);
// do stuff with x