2016-12-18 14 views
-1

私はエスケープされた制御文字を含む文字列を受け取り、エスケープしない関数をC++で実装する方法を知りたいとします(例えばHello\\nWorld\\nからHello\nWorld\nへ)。"stripslashes"はどのように実装できますか?

スラッシュで始まる各2文字のエスケープシーケンスから、対応する1文字の制御文字への大文字と小文字を区別せずに、このような機能を実装する方法はありますか?ここで

は私が渡したいテストケースです:

#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

スラッシュが追加された文字列があるかどうかを確認するために、「\ n」を「\ n」などのエスケープされたコントロールリテラルを有効にするためにどのように「評価する」ことができますか? – Dmitry

+3

ソースコードの文字列リテラルに表示されるものが、実行時に入力として得られるものと混同しています。あなたの説明を見てください( "Hello \ nWorld \ n"から "Hello \ nWorld \ n") - 混乱を見ますか?彼らはどちらも同じです。 "\\ n"に関しては、入力として取得された場合は、ユーザーが1つのスラッシュに続いて 'n'をタイプし、デバッガ(または文字列を表示しているもの)に "\\ n " – PaulMcKenzie

答えて

1

それはあなたがルックアップテーブルを使用したCAスイッチを最適化したい場合はエスケー

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

私は(2文字のstd ::文字列を制御文字にマッピングするO(1)マップの場合を除いて)それを考慮していましたが、あなたの解決策ではプログラムは1文字ごとにO(N)驚くほど高速ですが、醜い)、私の解決策は、すべてのペアを辞書に追加するための高価なインストール費用を必要とします。私は既にテーブルを利用できるように設定されているC++ランタイムユーティリティがあることを期待していました。 std :: arrayで構築されたstd :: unordered_mapがあるかどうかは分かりませんが、それ以外の場合は実際には実行できない場合があります(std配列から順序付けされていないマップを静的に構築していない限り)。 – Dmitry

+0

- コンパイル時に構築されたものは、実際にコンパイル時に作成されるか、それでもテーブルを設定するためのインストールコストがある場合です。それでも、どちらのソリューションも醜いセットアップコードや定型コードが必要です。 – Dmitry

+0

は、可能なバックスラッシュ文字が一意であるため、実際には単一の256バイト配列で十分です。エスケープされたシーケンスの別個の部分のバイトで簡単に参照します。たとえば、 '\\ n'の場合は 'n'です。 – Dmitry

関連する問題