2016-12-13 18 views
3

ostringstreamの文字を文字列の内容で置き換えて文字を置き換える方法を探していましたが、非常に非効率的な解決策があり、stringを抽出して修正してostringstreamは自動的に文字列ストリームの文字を置き換えます

今、文字列を追加するときに自動的にそれらの文字を置き換える方法があるのだろうかと思います。例えば。

ostringstream my_json; 
my_json << replace_singlequotes; # modify the stringsteam once 
my_json << "{'this':"; 
my_json << " 'is valid JSON'}"; 
std::cout << my_json.str(); 

output: 
{"this": "is valid JSON"} 

あなたがストリームに配管する前に、指定された文字列を変更するなどstd::hexのような形式修飾子に似ostringstream、用のカスタムフィルタを書くことができますか?

ostringstreamの文字を置き換える方法が他にありますか?std::replace()my_json.str()で実行することは、他の質問やハウツーに示唆されているとおりですか?

+0

2番目のコードスニペットが最初のコードスニペットよりも役立つと思います。 –

+1

注:引用符をエスケープする簡単な方法でjsonを書くだけであれば、生の文字列: 'R"({"this": "は有効なJSON"}) "'を使用することができます。 – Jarod42

答えて

2

この目的でユーザー定義マニピュレータを使用できます。次のように例を参照してください。

#include <iostream> 
#include <sstream> 

class replace_singlequotes { 
    friend std::ostream& operator<<(std::ostream &, const replace_singlequotes &); 
private: 
    std::string str; 
public: 
    replace_singlequotes(std::string); 
}; 

replace_singlequotes::replace_singlequotes(std::string str) { 
    this->str = str; 
} 

std::ostream& operator<<(std::ostream& os, const replace_singlequotes &value) { 
    std::string result = value.str; 
    for (int i = 0; i < result.length(); i++) { 
     if (result.at(i) == '\'') { 
      result.at(i) = '\"'; 
     } 
    } 
    os << result; 
    return os; 
} 

int main() { 
    std::ostringstream my_json; 
    my_json << replace_singlequotes("{'this': 'is valid JSON'}"); 
    std::cout << my_json.str() << std::endl; 
    return 0; 
} 

次のように出力は次のようになります。

{"this": "is valid JSON"} 

アップデート:ここでは、演算子のオーバーロードの概念を使用してこれを行うのひとつ別の方法である:

#include <iostream> 
#include <sstream> 

class String { 
private: 
    std::string value; 
public: 
    String operator=(const std::string value); 
    friend std::ostream & operator<< (std::ostream &out, String const &str); 
    friend std::istream& operator>>(std::istream& in, String &str); 
}; 

std::ostream & operator<<(std::ostream &out, const String &str) { 
    std::string result = str.value; 
    for (int i = 0; i < result.length(); i++) { 
     if (result.at(i) == '\'') { 
      result.at(i) = '\"'; 
     } 
    } 
    out << result; 
    return out; 
} 

std::istream& operator>>(std::istream& in, String &str) { 
    in >> str.value; 
    return in; 
} 

String String::operator=(const std::string value) { 
    this->value = value; 
    return *this; 
} 

int main() { 
    std::stringstream out; 
    String str; 

    str = "{'this': 'is valid JSON'}"; 
    out << str; 

    std::cout<<out.str(); 
    return 0; 
} 

注:

    上記のプログラムはまた、ここで {"this": "is valid JSON"}
  • と同じ出力を生成します
  • 、利点は、二重引用符で単一引用符を置き換えるために直接insertion operator (<<) を使用することができるということです。
  • 上記のコードスニペットでは演算子オーバーロードの概念を使用していますが、 初期例ではユーザー定義マニピュレータを使用していました。

あなたが希望の場合は、これとオーバーロードの概念を組み合わせることマニピュレータとしてreplace_singlequotesと を使用したい場合は、私はあなたが以下の手順に従っ を示唆している:

  1. booleanを宣言し クラスのreplace_singlequotesという名前のフラグ。
  2. staticにしてください。
  3. フラグの値がtrue/falseであることを確認し、挿入演算子のオーバーロードされた本文(<<)の一重引用符を二重引用符で置き換えるために があるかどうかを決定します。
+0

あなたは関数 'string replace_singlequotes(string s){replace(s.begin()、s.end()、 '\' '、'" '); return s;} 'を返すことはできません。結果はあなたの最初の例のように?問題は 'stringstream'の状態を変更するのではなく、毎回' replace_singlequote() 'と書かなければならないということです。 – frans

+0

はい。あなたはできる。しかし、これはマニピュレータの例を示すものではありません。しかし、2番目の例を見ると、 'replace_singlequote()'と書く必要はありません。なぜなら、挿入演算子自体の定義がそれを処理するからです。 –

関連する問題