создавая ostream - PullRequest
       9

создавая ostream

5 голосов
/ 07 февраля 2009

Я пытаюсь создать o ++ ostream по образовательным соображениям. Моим тестом будет создание ostream, который действует как ofstream, за исключением того, что вместо записи в файл он записывает в контейнер deque или vector.

Ответы [ 4 ]

11 голосов
/ 08 февраля 2009

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

Звучит так, будто вы хотите создать реализацию streambuf, которая затем записывает в вектор / дек. Примерно так (копирование из другого моего ответа, что предназначено для потока / dev / null ):

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;

Или что-то подобное ... Ну, я не проверял это. Но, возможно, это тоже хорошо - поэтому, если в нем все еще есть ошибки, вы можете попробовать их исправить.

4 голосов
/ 07 февраля 2009

Использовать std :: stringstream

#include <iostream>
#include <sstream>
int main()
{
    std::stringstream   s;
    s << "Plop" << 5;

    std::cout << s.str();
}
2 голосов
/ 08 февраля 2009

Я просто отмечу, что вам не нужно для этого писать ostream-подобный класс. Вы можете использовать адаптер для достижения своей цели.

Например, этот код читает из istream и вставляет каждый элемент в вектор:

vector<string> V;
copy(istream_iterator<string>(cin), 
     istream_iterator<string>(), 
     back_inserter(V)); 
1 голос
/ 07 февраля 2009

Без более подробной информации о том, что вы хотите сделать, сложно быть слишком конкретным, но вы не хотите создавать новый ostream. Что вы хотите сделать, так это создать новый тип streambuf и использовать существующий ostream.

Самое простое, что нужно сделать - это унаследовать от std :: basic_filebuf <> и перегрузить методы sync () и overflow () для добавления элементов в структуры данных.

...