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

C++ Binary to Decimal and Back Converter

本文关键字:转换器 十进制 二进制 C++      更新时间:2023-10-16

我几乎解决了这个练习:二进制到十进制和反向转换器 - "开发一个转换器,将十进制数转换为二进制或二进制数转换为十进制等效项。因此,二进制到十进制转换器可以完美运行,但另一个则不然。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;
}

使用 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] = '';
    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

你的错误是返回一个局部变量,当

函数返回时,局部变量会自动释放,因此你得到了垃圾。

当你做这样的事情时:

char *toString(...)
{
    char res[MAX_RES];
    // fill res
    return res;
}

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

如果要使用 C 样式的字符缓冲区,有两种方法可以解决此问题:

堆上分配结果。

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