Question

I have an istream (ifstream, in this case), and I want to write a specific number of characters from it into an ostream (cout, to be specific).

I can see that this is possible using something like istream.get(), but that will create an intermediate buffer, which is something I'd prefer to avoid.

Something like:

size_t numCharacters = 8;
ostream.get(istream, numCharacters);

Can someone point me in the right direction?

Thanks for reading :)

Edit: added c++ tag Edit: fixed title :/

New Edit:

Thanks very much for the answers guys. As a side note, can anyone explain this weird behaviour of copy_n? Basically it seems to not consume the last element copied from the input stream, even though that element appears in the output stream. The code below should illustrate:

string test = "testing the weird behaviour of copy_n";
stringstream testStream(test);

istreambuf_iterator<char> inIter( testStream );
ostream_iterator<char> outIter( cout );

std::copy_n(inIter, 5, outIter);
char c[10];
testStream.get(c,10);
cout << c;

The output I get is:

testiing the w

The output I would expect is:

testing the we

Nothing in the docs at cppreference.com mentions this kind of behaviour. Any further help would be much appreciated :)

My workaround for the moment is to seek 1 extra element after the copy - but that's obviously not ideal.

Était-ce utile?

La solution

You won't be able to avoid copying the bytes if you want to limit the number of characters and you want to be efficient. For a slow version without a buffer you can use std::copy_n():

std::copy_n(std::istreambuf_iterator<char>(in),
             std::istreambuf_iterator<char>(),
             std::ostreambuf_iterator<char>(out),
             n);

I'd be pretty sure that this is quite a bit slower than reading a buffer or a sequence thereof and writing the buffer (BTW make sure to call std::ios_base::sync_with_stdio(false) as it is otherwise likely to be really slow to do anything with std::cout).

You could also create a filtering stream buffer, i.e., a class derived from std::streambuf using another stream buffer as its source of data. The filter would indicate after n characters that ther are no more characters. It would internally still use buffers as individual processing of characters is slow. It could then be used as:

limitbuf buf(in, n);
out << &buf;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top