Я пытаюсь создать С++ ostream по образовательным причинам. Мой тест будет создавать ostream, который действует как ofstream, за исключением того, что вместо записи в файл он будет писать в deque или векторный контейнер.
создание острима
Ответы (4)
Так как это для образования, как вы говорите, я покажу вам, как бы я сделал такую штуку. В противном случае stringstream
действительно правильный путь.
Похоже, вы хотите создать реализацию streambuf, которая затем записывает в vector/deque. Что-то вроде этого (копирование из другого моего ответа, который нацелен на /dev/нулевой поток):
template<typename Ch, typename Traits = std::char_traits<Ch>,
typename Sequence = std::vector<Ch> >
struct basic_seqbuf : std::basic_streambuf<Ch, Traits> {
typedef std::basic_streambuf<Ch, Traits> base_type;
typedef typename base_type::int_type int_type;
typedef typename base_type::traits_type traits_type;
virtual int_type overflow(int_type ch) {
if(traits_type::eq_int_type(ch, traits_type::eof()))
return traits_type::eof();
c.push_back(traits_type::to_char_type(ch));
return ch;
}
Sequence const& get_sequence() const {
return c;
}
protected:
Sequence c;
};
// convenient typedefs
typedef basic_seqbuf<char> seqbuf;
typedef basic_seqbuf<wchar_t> wseqbuf;
Вы можете использовать его следующим образом:
seqbuf s;
std::ostream os(&s);
os << "hello, i'm " << 22 << " years old" << std::endl;
std::vector<char> v = s.get_sequence();
Если вы хотите иметь очередь как последовательность, вы можете сделать это:
typedef basic_seqbuf< char, char_traits<char>, std::deque<char> > dseq_buf;
Или что-то подобное... Ну, я не проверял. Но, может быть, это и хорошо, так что, если он все еще содержит ошибки, вы можете попробовать их исправить.
overflow
принимает по одному символу за раз) или есть ли способ пересечь basic_streambuf::sputn(const char* s, streamsize n)
?
- person dma_k; 14.02.2011
Используйте std::stringstream
#include <iostream>
#include <sstream>
int main()
{
std::stringstream s;
s << "Plop" << 5;
std::cout << s.str();
}
std::cout << std::bitset<4>(5) << "\n";
- person Martin York; 05.11.2019
Я просто отмечу, что вам не нужно писать для этого класс, подобный ostream. Вы можете использовать адаптер для достижения своей цели.
Например, этот код читает из istream и вставляет каждый элемент в вектор:
vector<string> V;
copy(istream_iterator<string>(cin),
istream_iterator<string>(),
back_inserter(V));
Без более подробной информации о том, что вы хотите сделать, трудно быть слишком конкретным, но вы не хотите создавать новый ostream. Что вы хотите сделать, так это создать новый тип streambuf и использовать существующий ostream.
Проще всего наследовать от std::basic_filebuf‹> и перегружать методы sync() и overflow() для добавления элементов в ваши структуры данных.