将二进制字符的字符串表示转换为字符串的最佳方法

Best method to convert a string rapresentation of binary chars to a string of chars

本文关键字:字符串 最佳 方法 表示 二进制字符 转换      更新时间:2023-10-16

我创建了一个自定义numpunct类,该类允许我创建一个具有用户定义值的自定义numpunc(在我的情况下,千位分隔符、十进制分隔符和分组将从xml文档中读取)。这是我的课:

class custom_numpunct : public std::numpunct<char>
{
public:
  custom_numpunct(const char decimal_point, const char thousands_sep, const std::string grouping)
    : cDecimalPoint(decimal_point), cThousandsSep(thousands_sep), sGroup(grouping) {}
protected:
  virtual char do_decimal_point() const { return cDecimalPoint; }
  virtual char do_thousands_sep() const { return cThousandsSep; }
  virtual std::string do_grouping() const { return sGroup; }
  const char cDecimalPoint;
  const char cThousandsSep;
  const std::string sGroup;
};

主要问题是分组接受二进制字符来进行分组。因此,如果我直接使用这样的代码中的值

std::string grouping = "123";

它之所以有效,是因为它们是二进制值。问题是从用户输入中读取,我会有

std::string grouping = "\1\2\3";

(用户插入\ 1\2\3)所以我需要一些东西来将字符串二进制表示转换为实际字符。我创建了这个功能

std::string convertToBinary(std::string input)
{
  std::stringstream out;
  std::stringstream ss(input);
  std::string tok;
  int value;
  while (std::getline(ss, tok, '')) 
  {
    if (!tok.empty())
    {
      try 
      {
        value = std::stoi(tok);
      }
      catch (const std::invalid_argument& ia) 
      {
        std::cerr << "Invalid argument: " << ia.what() << std::endl;
        continue;
      }
      out << (char)(value & 0xff);
    }
  }
  return out.str();
}

它用\分割字符串,并尝试使用字符串将单个整数转换为字符,但它可能不可靠(1也是有效的二进制输入)。有更好的方法来进行转换吗?

我会这样做:

string convertToBinary(const string& in)
{
    string out;
    out.reserve(in.size() / 2);
    for (const char *cur = in.c_str(), *end = cur + in.size(); cur != end; ++cur) {
        if (*cur == '') {
            ++cur; // skip first backslash                                                                              
            if (cur == end) {
                break;
            }
            if (isdigit(*cur)) { // found escape sequence                                                               
                char* end;
                unsigned long num = strtol(cur, &end, 10);
                cur = end - 1;
                out.push_back(num);
                continue;
            }
        }
        out.push_back(*cur);
    }
    return out;
}

如果我调用convertToBinary("\1\233"),我会得到一个有两个字节的字符串,即十进制的1和233。任何后面没有数字的反斜杠都会被跳过,因此例如"\n"变成"n"

顶部的reserve()调用可以根据您的典型输入数据进行调整。如果你的输入总是充满转义序列,例如"\1\10\100",你可能想除以3,但如果你的输出可能没有很多转义,你可能只想使用完整的in.size()