逃逸一个C++;一串 什么是将C++ STD::string转换成另一个STD::string的最简单方法,它有所有不可打印的字符都被释放了?p>

逃逸一个C++;一串 什么是将C++ STD::string转换成另一个STD::string的最简单方法,它有所有不可打印的字符都被释放了?p>,c++,string,boost,escaping,C++,String,Boost,Escaping,例如,对于两个字符的字符串[0x61,0x01],结果字符串可能是“a\x01”或“a%01”。一个人的不可打印字符是另一个人的多字节字符。因此,您必须先定义编码,然后才能确定哪些字节映射到哪些字符,哪些字符是不可打印的。看看Boost的功能。您可以使用它的分类器(及其运算符!重载)来挑选不可打印的字符,它的函数可以用您想要的任何格式替换这些字符 #include <iostream> #include <boost/format.hpp> #include <bo

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

一个人的不可打印字符是另一个人的多字节字符。因此,您必须先定义编码,然后才能确定哪些字节映射到哪些字符,哪些字符是不可打印的。

看看Boost的功能。您可以使用它的分类器(及其运算符!重载)来挑选不可打印的字符,它的函数可以用您想要的任何格式替换这些字符

#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;
}
#包括
#包括
#包括
结构字符转义器
{
模板
std::string运算符()(const FindResultT&Match)const
{
std::字符串s;
for(typename FindResultT::const_iterator i=Match.begin();
i!=Match.end();
(i++){
s+=str(boost::format(\\x%02x”)%static_cast(*i));
}
返回s;
}
};
int main(int argc,字符**argv)
{
std::字符串s(“a\x01”);
boost::find_format_all(s,boost::token_finder(!boost::is_print()),character_escaper());

std::cout假设执行字符集是ASCII的超集,字符位为8。对于输出者,传递回插入器(例如,向量或其他字符串)、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;
}
模板
OutIter write_转义(std::string const&s,OutIter out){
*out++='“';
for(std::string::const_迭代器i=s.begin(),end=s.end();i!=end;++i){
无符号字符c=*i;
如果('4];
*out++=hexdig[c&0xF];
}
}
}
*out++='“';
返回;
}

你看过关于如何做的文章吗?

假设“最简单的方法”的意思是简单易懂,但不依赖任何其他资源(如LIB),我会这样做:

#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
    // the cast is necessary to avoid undefined behaviour
    if(isprint((unsigned char)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;
    }
}
#包括
#包括
//s是转义的输出字符串
std::string s=“”;
//循环遍历所有字符
for(字符c:您的_字符串)
{
//检查给定字符是否可打印
//为了避免未定义的行为,强制转换是必要的
if(isprint((无符号字符)c))
s+=c;
其他的
{
std::stringstream;
//如果字符不可打印
//我们将使用stringstream将其转换为十六进制字符串
//注意,由于char是有符号的,我们必须首先将其转换为unsigned

最简单的逃生方法是通过“急诊科”,在代码< > 0 旁边。我认为& &是一个非常好的操作员。甚至可以使用它而不需要额外的头文件。你可以在标准C++中使用和不带头。这是从另一个项目中复制的,我忘记了修改那些以弥补MSVC的缺陷。Cincies。为什么编写时需要传入一个
back\u inserter
(十六进制,5,“\x%02x”,c);S+= STD::字符串(HEX,LEN);在<代码> E/St>中,也有一些我没有看到的东西。OP没有明确地要求一个纯C++解决方案,但我认为听起来像他更喜欢C++。所以我把自己限制在了这一点上。但是,是的,就我而言,您的代码将工作相同。(而且会短一点。)解决方案中存在一个错误。iPrint方法需要int>-1和127,这意味着负的
字符c
。这是我的版本:@Tom你是对的。我在stringstream部分正确地铸造了字符,但在
iPrint
内部没有铸造。尽管测试了更高的ASCII代码,但由于gcc的实现n似乎总是返回false,除非它是可打印的字符。然而,未定义的行为是邪恶的,所以我更正了我的原始代码。