C++:替换字符串中控制字符的最佳方法

laximzn5  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(147)

对于解析工作,我有一个字符串,它基本上可以是任何东西。

"something \t \n \0 \whatever else"

在解析结束时,我需要将输出序列化,使其易于使用JSON......这意味着我需要去掉控制字符。对于所有的值条目,我运行一个字符串清理程序:

void sanitizer(std::string & value){
   for (auto& it : value){
     if ((int) sit <= 31 || (int) sit == 127){
        if (sit == '\t')
            std::cout << "\\t";
        else if (sit == '\r')
            std::cout << "\\r";
        else if (sit == '\0')
            std::cout << "\\0";
        else if (sit == '\n')
            std::cout << "\\n";

        else 
            std::cout << " ";
      } else if (sit == '"'){
          std::cout << '\'';
      } else if (sit == '\\')
          std::cout << "/";
      else 
          std::cout << sit;
    }

但是,仅这个函数就占据了解析器中大约44%的时间。
当我消除std::cout调用,而是构建一个字符串,然后打印到cout时,这会进一步降低速度。
有没有一种优化的方法可以用C++替换/转义字符串中的这些控制字符?

yqkkidmi

yqkkidmi1#

一种方法是将std::iscntrl函数与std::remove_if沿着使用:

void remove_control_characters(std::string& s) {
    s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return std::iscntrl(c); }), s.end());
}

进一步的改进是实现您自己的字符分类函数。std::iscntrl使用当前的全局locale对象。

rjee0c15

rjee0c152#

下面的内容是否适合您的目的?

void sanitizer(std::string & value) {
    std::string prev_loc = std::setlocale(LC_ALL, nullptr);
    std::setlocale(LC_ALL, "en_US.iso88591");
    std::replace_if(value.begin(), value.end(), [](unsigned char c){ return std::iscntrl(c); }, ' ');
    std::setlocale(LC_ALL, prev_loc.c_str());
}

相关问题