c++streammanipulators

Does the output manipulator std::ends add a Null-character to the output buffer?


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.

Here is the output:

Hello!╠╠╠╠╠╠ظش↕♠L·6
Hello!╠╠╠╠╠╠ظش↕♠L·6Hello!╠╠╠╠╠╠ظش↕♠L·6

Thank you.


Solution

  • 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));