Преобразование std::ostringstream в std::stringstream

Следующий код возвращает пустую строку в ss:

#include <string>       
#include <iostream>     
#include <sstream>      

int main () {
  std::ostringstream oss;
  oss << "Text";

  std::stringstream ss;
  ss.basic_ios<char>::rdbuf(oss.rdbuf());
  std::cout << ss.str() << "\n";
  return 0;
}

Как я могу вернуть из ss текст, представленный в oss? Меня в основном интересует преобразование std::ostringstream в std::stringstream.


person Medical physicist    schedule 16.04.2020    source источник
comment
Почему вы не можете использовать oss.str() вместо этого? Какую реальную проблему вам нужно решить? Сейчас это слишком много XY-проблемы.   -  person Some programmer dude    schedule 16.04.2020
comment
@Someprogrammerdude Настоящая проблема слишком длинная, но она будет решена, если я найду решение этой.   -  person Medical physicist    schedule 16.04.2020
comment
@Medicalphysicist прочитайте еще раз, какова природа XY problem (длина не имеет к этому никакого отношения), вы спрашиваете, как исправить недопустимое решение, а не как правильно решить реальную проблему.   -  person Marek R    schedule 16.04.2020
comment
Если у вас есть что-то в ss, и вы пытаетесь объединить ss с oss, вы можете просто использовать std::cout << ss.str() << oss.str() << "\n"; Это более эффективно, чем пытаться объединить их в один объект только для печати. Если вам нужна одна строка, просто верните ss.str() + oss.str()   -  person NathanOliver    schedule 16.04.2020
comment
Давайте сделаем шаг назад и посмотрим, что вы просите, чтобы понять, почему вы не можете этого сделать. oss – это выходной поток. Когда вы делаете ss.basic_ios<char>::rdbuf(oss.rdbuf()); (или сокращение от ss << oss.rdbuf()), вы просите прочитать из oss. Это не сработает, поскольку oss предназначено для записи, а не для чтения.   -  person NathanOliver    schedule 16.04.2020
comment
Спасибо, @NathanOliver. Есть ли способ преобразовать std::ostringstream в std::stringstream без использования .str()?   -  person Medical physicist    schedule 16.04.2020
comment
Насколько я знаю, № oss предназначен для записи, а не для чтения.   -  person NathanOliver    schedule 16.04.2020
comment
@Medicalphysicist Разве мой ответ не сделал то, что вы хотели?   -  person Ted Lyngmo    schedule 18.04.2020
comment
@TedLyngmo Спасибо за ваш ответ, это было очень полезно. Но самым полезным решением стал комментарий Натана Оливера.   -  person Medical physicist    schedule 19.04.2020
comment
@Medicalphysicist Добро пожаловать. Как вам удалось использовать комментарий Натана, чтобы вернуть из ss текст, представленный в oss? Вы должны сами написать ответ на свой вопрос и описать, как это сделать, чтобы другие могли им воспользоваться.   -  person Ted Lyngmo    schedule 19.04.2020


Ответы (2)


Вы можете использовать защищенную функцию-член std::streambuf::swap, которая обменивается содержимым буфера потока с буфером другого

Чтобы получить к нему доступ, вам понадобится производный класс:

#include <iostream>
#include <sstream>

struct swapper : std::streambuf {
    using std::streambuf::streambuf;
    void swap(std::streambuf& rhs) {         // public proxy for protected swap
        std::streambuf::swap(rhs);
    }
};

// casting
void swapbuf(std::ostream& a, std::ostream& b) {
    static_cast<swapper*>(a.rdbuf())->swap(*b.rdbuf());
}

int main () {
    std::ostringstream oss;
    oss << "Text";
    std::stringstream ss;
    swapbuf(oss, ss);

    std::cout << "ss:  " << ss.str() << "\n";   // prints Text
}
person Ted Lyngmo    schedule 16.04.2020
comment
Именно поэтому защищенный - плохая идея. Такое оскорбление. - person Martin York; 18.04.2020
comment
@MartinYork Думаю, можно заменить streambuf в потоках строк экземплярами настроенного streambuf, чтобы сделать его не оскорбительным. - person Ted Lyngmo; 18.04.2020

Следуя комментариям @NathanOliver, я решил преобразовать std::ostringstream в std::stringstream с помощью str():

#include <string>       
#include <iostream>     
#include <sstream>      

int main () {
  std::ostringstream oss;
  oss << "Text";

  std::stringstream ss;
  ss << oss.str();
  std::cout << ss.str() << "\n";
  return 0;
}
person Medical physicist    schedule 20.04.2020
comment
Хорошо, хотя это не ответ на вопрос, а мой ответ делает именно то, о чем вы просили. - person Ted Lyngmo; 21.04.2020