代码之家  ›  专栏  ›  技术社区  ›  Danra Bathsheba

逃出C++字符串

  •  18
  • Danra Bathsheba  · 技术社区  · 16 年前

    将C++ STD::string转换成另一个STD::String的最简单方法是什么?

    例如,对于两个字符的字符串[0x61,0x01],结果字符串可能是“a\x01”或“a%01”。

    5 回复  |  直到 16 年前
        1
  •  11
  •   Josh Kelley    16 年前

    看看提神器 String Algorithm Library . 您可以使用它的 is_print 分类器(及其运算符!重载)选择不可打印的字符,及其 find_format() 函数可以用任何格式替换这些内容。

    #include <iostream>
    #include <boost/format.hpp>
    #include <boost/algorithm/string.hpp>
    
    struct character_escaper
    {
        template<typename FindResultT>
        std::string operator()(const FindResultT& Match) const
        {
            std::string s;
            for (typename FindResultT::const_iterator i = Match.begin();
                 i != Match.end();
                 i++) {
                s += str(boost::format("\\x%02x") % static_cast<int>(*i));
            }
            return s;
        }
    };
    
    int main (int argc, char **argv)
    {
        std::string s("a\x01");
        boost::find_format_all(s, boost::token_finder(!boost::is_print()), character_escaper());
        std::cout << s << std::endl;
        return 0;
    }
    
        2
  •  9
  •   Roger Pate    16 年前

    假定执行字符集是ASCII的超集,并且 夏比特 是8。对于 排泄物 通过A 后退式插入器 (例如) 矢量<char> 或者另一个字符串), Ostream_迭代器 或任何其他合适的输出迭代器。

    template<class OutIter>
    OutIter write_escaped(std::string const& s, OutIter out) {
      *out++ = '"';
      for (std::string::const_iterator i = s.begin(), end = s.end(); i != end; ++i) {
        unsigned char c = *i;
        if (' ' <= c and c <= '~' and c != '\\' and c != '"') {
          *out++ = c;
        }
        else {
          *out++ = '\\';
          switch(c) {
          case '"':  *out++ = '"';  break;
          case '\\': *out++ = '\\'; break;
          case '\t': *out++ = 't';  break;
          case '\r': *out++ = 'r';  break;
          case '\n': *out++ = 'n';  break;
          default:
            char const* const hexdig = "0123456789ABCDEF";
            *out++ = 'x';
            *out++ = hexdig[c >> 4];
            *out++ = hexdig[c & 0xF];
          }
        }
      }
      *out++ = '"';
      return out;
    }
    
        3
  •  4
  •   Scindix    9 年前

    假设“最简单的方式”意味着简短但容易理解,而不依赖任何其他资源(如libs),我会这样做:

    #include <cctype>
    #include <sstream>
    
    // s is our escaped output string
    std::string s = "";
    // loop through all characters
    for(char c : your_string)
    {
        // check if a given character is printable
        if(isprint(c))
            s += c;
        else
        {
            std::stringstream stream;
            // if the character is not printable
            // we'll convert it to a hex string using a stringstream
            // note that since char is signed we have to cast it to unsigned first
            stream << std::hex << (unsigned int)(unsigned char)(c);
            std::string code = stream.str();
            s += std::string("\\x")+(code.size()<2?"0":"")+code;
            // alternatively for URL encodings:
            //s += std::string("%")+(code.size()<2?"0":"")+code;
        }
    }
    
        4
  •  3
  •   Douglas Leeder    16 年前

    一个人的不可打印字符是另一个人的多字节字符。因此,在计算出哪些字节映射到哪些字符,哪些字符不可打印之前,必须定义编码。

        5
  •  2
  •   hkaiser    16 年前