2016-12-13 2 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"} 

Вы можете написать собственный фильтр для ostringstream аналогичных модификаторов формата, как std::hex и т.д., который модифицирует данную строку перед тем обжигающе его в поток?

Или есть ли другой способ заменить символы в ostringstream, за исключением работы std::replace() на my_json.str(), как это предлагается в других вопросах и в хаотах?

+0

Я думаю, что второй фрагмент кода будет более полезен для вас, чем первый. –

+1

Примечание. Если вы хотите просто написать json, чтобы избежать цитаты, вы можете использовать необработанную строку: «R» ({«this»: «is valid 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"} 

Update: Вот один другой способ сделать это, используя понятие перегрузки операторов:

#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;} 'для достижения того же как в первом примере?Проблема в том, что вы должны писать 'replace_singlequote ()' каждый раз, а не изменять состояние 'stringstream'. – frans

+0

Да. Ты можешь. Но это не будет демонстрировать пример манипулятора. Но если вы посмотрите на второй пример, вам никогда не придется писать 'replace_singlequote ()', потому что само определение оператора вставки позаботится об этом. –