Функция для экранирования некоторых символов для строки C ++ - PullRequest
1 голос
/ 05 апреля 2020

Мне нужна функция для экранирования некоторых символов внутри std::string, и поэтому я сделал это:

static void escape(std::string& source,const  std::vector<std::string> & toEscape, const std::string& escape){
    //for each position of the string
    for(auto i = 0; i < source.size(); ++i){
        // for each substring to escape
        for(const auto & cur_to_escape : toEscape){
            // if the current position + the size of the current "to_escape" string are less than the string size and it's equal to the substring next of the i'th position
            if(i + cur_to_escape.size() < source.size() && source.substr(i, cur_to_escape.size()) == cur_to_escape){
                // then for each char of the current "to_escape", escape the current character with the "escape" string given as parameter
                /*
                 *  source = asd
                 *  toEscape = {"asd"}
                 *  escape = \
                 *  -> asd -> \asd -> \a\sd -> \a\s\d 
                 * */
                for(auto z = 0; z < cur_to_escape.size(); ++z){
                    source.insert(i, escape);
                    i+=escape.size();
                }
            }
        }
    }
}

и для проверки я использовал это:

int main() {
    std::string s = "need to escape \" , \\ and \n .";
    std::cout<<s;
    escape(s, {"\n", "\\", "\""}, "\\");
    std::cout<<"\n\n final string: "<<s;
}

и вывод

final string: need to escape \" , \\ and \
 .

и поэтому \n не был экранирован, как предполагалось ... и я не могу найти проблему ... какие-либо догадки?

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

«и поэтому \ n не был экранирован, как предполагалось» Да, это так: символ новой строки находится там, как и ожидалось. Если вы ожидаете 'n' символа, вы не правы. '\n' - это соглашение, используемое для представления «невидимого» символа New-Line (NL).

Вот более чистый способ написать то же самое ( попробовать это ):

std::string escape(const char* src, const std::set<char> escapee, const char marker)
{
  std::string r;
  while (char c = *src++)
  {
    if (escapee.find(c) != escapee.end())
      r += marker;
    r += c; // to get the desired behavior, replace this line with: r += c == '\n' ? 'n' : c;
  }
  return r;
}
//...
std::string r = escape("\"this\" is a test\nthis is the second line", { '"', '\n' }, '\\');
0 голосов
/ 05 апреля 2020

Это рабочий код, но он не оптимален и может быть выполнен быстрее, но, возможно, также больше.

void escape(std::string& source, const  std::vector<std::string>& to_escape, const std::string& escape) { 
    // for each substring to escape
    for (const auto &e : to_escape) {
        auto pos = source.find(e);
        while (pos != std::string::npos) {
            auto to_replace = escape+e;
            if (e=="\n") to_replace = escape+"n";
            else if (e=="\t") to_replace = escape+"t";
            source.replace(pos, e.size(), to_replace);
            const auto old_pos = pos;
            pos = source.find(e, old_pos + to_replace.size());
        }
    }
}

Живой код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...