【问题标题】:C++ Binary to Decimal and Back ConverterC++ 二进制到十进制和反向转换器
【发布时间】:2015-02-27 18:15:24
【问题描述】:

我几乎解决了这个练习: 二进制到十进制和反向转换器 - “开发一个转换器以将十进制数转换为二进制或将二进制数转换为其十进制等效值。” 所以,二进制到十进制转换器工作得很好,但另一个没有。 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;
}

【问题讨论】:

  • 你可以使用bitwise operators吗?
  • 废话来自返回本地数组的地址binary。您应该使用 std::string 而不是 char 数组,或者您应该在堆上分配 char 数组。
  • 而且还使用编译器警告,你会知道的。
  • 是的。我知道它们是如何工作的,但我从未真正使用过它们。
  • 你应该在这种情况下。

标签: c++ converter


【解决方案1】:

使用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

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

【讨论】:

    【解决方案2】:

    当你做这样的事情时:

    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 明确释放。这种方法的优点是您可以根据需要制作任意长度的字符串。缺点是分配可能会失败。还值得注意的是,调用者现在拥有该字符串并负责freeing 它:

    char *x = toString(...);
    
    // do stuff with x
    free(x);
    

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

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

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

    它是这样称呼的:

    char x[200];
    
    toString(x, sizeof(x), ...);
    // do stuff with x
    

    【讨论】:

      猜你喜欢
      • 2013-05-14
      • 2020-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-26
      • 1970-01-01
      • 2017-01-18
      • 2014-07-31
      相关资源
      最近更新 更多