Domanda

Sto cercando di creare un ++ ostream c per motivi pedagogici. La mia prova sarà la creazione di un ostream che agisce come un ofstream sarebbe tranne che invece di scrivere su un file che sarebbe scrivere in un contenitore deque o vettoriale.

È stato utile?

Soluzione

Per quanto lo è per l'educazione, come dici tu, io vi mostrerò come mi piacerebbe fare una thingy. In caso contrario, stringstream è davvero la strada da percorrere.

Sembra che si desidera creare un'implementazione streambuf che poi scrive a un vettore / deque. Qualcosa di simile a questo (copia da un'altra risposta di me che di mira un / dev / null flusso ):

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;

Si può usare in questo modo:

seqbuf s;
std::ostream os(&s);
os << "hello, i'm " << 22 << " years old" << std::endl;
std::vector<char> v = s.get_sequence();

Se si desidera avere un deque come una sequenza, è possibile farlo:

typedef basic_seqbuf< char, char_traits<char>, std::deque<char> > dseq_buf;

o qualcosa di simile ... Beh non ho provato. Ma forse è anche una buona cosa - quindi se contiene ancora bug, si può provare risolverli.

Altri suggerimenti

L'uso std :: stringstream

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

    std::cout << s.str();
}

mi limiterò a sottolineare che non è necessario scrivere una classe ostream simile per questo. È possibile utilizzare un adattatore per raggiungere il tuo obiettivo.

Ad esempio, il codice legge da istream e inserisce ogni elemento in un vettore:

vector<string> V;
copy(istream_iterator<string>(cin), 
     istream_iterator<string>(), 
     back_inserter(V)); 

Senza ulteriori dettagli su ciò che si vuole fare è difficile essere troppo specifico, ma non si vuole creare un nuovo ostream. Che cosa si vuole fare è creare un nuovo tipo di streambuf, e utilizzare un ostream esistente.

La cosa easyist da fare è ereditare da std :: basic_filebuf <>, e sovraccaricare lo sync () e troppo pieno () per aggiungere elementi alle vostre strutture di dati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top