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.

Was it helpful?

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top