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.
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;