2016-12-18 2 views
-1

Я хочу знать, как я могу реализовать функцию в C++, которая берет строку, которая содержит экранированные управляющие символы, и unescape их (например, Hello\\nWorld\\n - Hello\nWorld\n).Как я могу реализовать «stripslashes»?

Есть ли способ реализовать такую ​​функцию, не прибегая к отображению по каждому случаю из каждой двухсимвольной управляющей последовательности, которая начинается с косой черты с соответствующим символом управления символом?

Вот тест я хочу передать:

#include <string> 
#include <iostream> 
#include <stdio.h> 

using std::string; 

int main(int argc, char **argv) 
{ 
    // before transformation. 
    string given("Hello\\nWorld\\n"); 

    // after transformation. 
    string expected("Hello\nWorld\n"); 

    // transformation :: string -> string 
    auto transformation = [](const string &given) -> string { 
     // do something to strip slashes from given, and return it. 
     string result = given; 
     return result; 
    }; 

    string result(transformation(given)); 

    // test :: (string, string) -> bool 
    auto test = [](const string &result, const string &expected) -> bool { 
     // returns true if the two given strings are equal, false otherwise. 
     return (result.compare(expected) == 0); 
    }; 

    puts(given.c_str()); 
    puts(result.c_str()); 
    std::cout << "test result: " << test(result, expected) << "\n"; 

    return 0; 
} 
+0

Непонятно, о чем вы просите. Эквивалентные последовательности возникают только в строковых/символьных литералах исходного кода C++. – PaulMcKenzie

+0

Я спрашиваю, есть ли у меня строка с добавленными косыми чертами, как я могу «eval» их превратить экранированные управляющие литералы, такие как «\\ n» в «\ n». – Dmitry

+3

Вы вводите в замешательство то, что вы видите в ваших литералах строки исходного кода, к чему-то, что вы можете получить в качестве входных данных во время выполнения. Посмотрите на свое описание («Hello \ nWorld \ n» на «Hello \ nWorld \ n»). См. Путаницу? Они одинаковы. Что касается «\\ n», если вы получите это как вход, это означает, что пользователь набрал одну косую черту, за которой следует «n», а ваш отладчик (или все, что вы просматриваете строку), возможно, показывает «\\ n ». – PaulMcKenzie

ответ

1

Это не трудно написать беглец

std::string stripslashes(std:string const &str) 
    { 
    std::string answer; 
    int i = 0; 

    while(i < str.size()) 
    { 
     if(i != '\\') 
      answer.pushback(str[i++]); 
     else 
     { 
      switch(str[i+1]) 
      { 
       case 'n': answer.push_back('\n'); break; 
       case 't': answer.push_back('\t'); break; 
       ... etc 
      } 
      i += 2; 
     } 
    } 
    return answer 
    } 

Если вы хотите оптимизировать переключатель вы ч использовать справочную таблицу, но это вряд ли стоит.

+0

Я рассматривал это (кроме как с неупорядоченной картой для O (1) отображения 2 символа std :: strings для управляющих символов), но пока ваше решение делает программу для цикла O (N) для каждого отдельного символа (который является удивительно быстрый, но уродливый), и мое решение требует дорогостоящей стоимости установки для добавления всех пар в словарь. Я надеялся, что есть утилита выполнения C++, которая уже имеет таблицы, созданные для использования; но в противном случае было бы невозможно сделать это без вашего собственного времени выполнения (если вы не статически не построили неупорядоченную карту из массива std, но im not sure) - – Dmitry

+0

- я не уверен, что std :: unordered_map, построенный с помощью std :: array построенный во время компиляции, действительно создается во время компиляции или если у него все еще есть стоимость установки для настройки таблицы. Даже тогда оба решения требуют уродливого кода установки или кода шаблона. – Dmitry

+0

действительно уверен, что одного 256-байтового массива достаточно, так как каждый возможный обратный символ уникален. простой поиск по байту отдельной части экранированной последовательности, например 'n' для '\\ n' – Dmitry

Смежные вопросы