Again reading C++ primer 5ed I have a simple question:
It is said that the manipulator std::ends
inserts a Null-character \0
to the output buffer then flushes it.
So I tried to understand it through an example:
#include <iostream>
int main() {
char sz[]{ 'H', 'e', 'l', 'l', 'o', '!' }; // no null-terminator character ('\0')
std::cout << sz; // Hello!
std::cout << sz << std::flush;
std::cout << sz << std::ends;
}
Above in the first output line I get some unreadable characters appended to the array of characters; Ok because I didn't add a null-character \0
to sz
.
In the second line it is OK the output looks like the first but forces flushing the buffer.
What matters me the third line using std::ends
; it is said that this manipulator inserts a Null-Character into the output buffer but the output is the same as the lines above it; Which prints unreadable trailing characters which I guess that std::ends
didn't insert \0
in the output buffer?!
Here is the output:
Hello!╠╠╠╠╠╠ظش↕♠L·6
Hello!╠╠╠╠╠╠ظش↕♠L·6Hello!╠╠╠╠╠╠ظش↕♠L·6
Thank you.
std::ends
is an archaic manipulator intended to be used for the now-deprecated array I/O streams like std::strstream
, std::istrstream
, and std::ostrstream
. You will rarely if ever have to use it in practice.
The problem in your code is that std::cout << sz << std::ends
first executes std::cout << sz
which will print the character array. The extractor overload over character arrays is designed to continue printing each character until it finds a null terminator. sz
does not end with one so the extractor is just going to keep iterating past the end of the array until it encounters a random null character in surrounding memory. What results from this is called undefined behavior. The compiler no longer has to conform to the logic of your code, and therefore the output can be meaningless garbage or it could print it in a way that appears like the code is working. Undefined behavior means undefined.
Adding << std::ends
will not null-terminate the character array, it's a separate operation that executes after the first expression has been executed.
If you'd like to print the character array as-is I would recommend using write
:
std::cout.write(sz, sizeof(sz));