0
#include<iostream>

using namespace std;

#define sp ' '

std::ostream& nl(std::ostream os)
{
    return os << '\n';
}



int main()
{
    cout << 1 << sp << 2 << nl;
    cout << 3 << sp << 4 << sp;
    cin.get();
    cout << 5 << sp << 6 << nl;
    cin.get();
    cout << 7 << sp << 8;

    return 0;
}

I'm testing out my own stream manipulator that adds newline but doesn't flush. I'm expecting no output until the end of program, since cout is supposed to only flush at the end of the program without endl. And also I'm expecting output to be

1 2
3 4
// newline added here and cin.get() executed adding another newline
5 6
// newline added here and cin.get() executed adding another newline
7 8

But instead I'm getting this.

1 2007818983 4  // cin.get() executed here in this line
5 600781898 //cin.get() executed here again
7 8

Why is that? And during debugging in Visual Studio 2019, is there any way to view what cout's, cin's or any stream's buffer in the debugger to find out what's going on?

leopra
  • 17
  • 4
  • A lot of systems have stdout line-buffered when writing to a console - which means it flushes every time a newline is printed. Files aren't line-buffered so they don't flush until endl or the file is closed. So maybe test your stuff when writing to a file? See this https://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-strin On the other hand you can turn off buffering https://stackoverflow.com/questions/7876660/how-to-turn-off-buffering-of-stdout-in-c – Jerry Jeremiah Mar 14 '22 at 06:38
  • *"since cout is supposed to only `flush` at the end of the program without `endl`."* -- I believe this is false. Do you have a source for this? (Also, how is your approach supposed to be an improvement over simply streaming the character literal `'\n'` instead of using your `nl` function? If you like the name, then why not just something like `constexpr char nl = '\n'`?) – JaMiT Mar 14 '22 at 06:41
  • @JerryJeremiah I did that also and I'm getting the same output. Only difference is its all in one line. Why are the extra numbers there? – leopra Mar 14 '22 at 06:42
  • @JaMiT I have read that modern compilers have their own flushing mechanisms so it decides on its own when to flush, sometimes even regardless of `endl`. I only wrote this code as an exercise to learn making functions that manipulate text in a stream. But why am I getting all these extra characters? – leopra Mar 14 '22 at 06:45
  • @user4581301 I see! Thanks! – leopra Mar 14 '22 at 06:51
  • Hit enter too soon to accept a typo fix. Anyway, here's what I meant to say: You're going to find that there is a lot of leeway. If something is required to happen, it'll happen (or the implementation is not Standard-compliant). In this case the standard only specified when the implementation must flush and does not specify when it must not flush. – user4581301 Mar 14 '22 at 06:57
  • @leopra *"modern compilers have their own flushing mechanisms so it decides on its own when to flush, sometimes even regardless of `endl`"* -- this contradicts the claim made in your question, as this states that flushing might happen more often, not less. And it's not completely "regardless" of `endl`; if a flush is requested (usually via `endl` or `flush`), then a flush must happen. What you read is basically saying that a program does not have to wait for a requested flush to actually write. – JaMiT Mar 14 '22 at 07:01
  • @JaMiT This is given as an example in the book `Thinking in C++` Vol 2 on page 99. It depicts `creating your own manipulator `to work with `std::ofstream` to `add a new line without flushing!`. I had previously that `cout` decides itself when to `flush`. So I thought I was missing something. Thanks for all the great help provided! Much appreciated! – leopra Mar 14 '22 at 07:08
  • 1
    @leopra *"to work with `std::ofstream` to [...]"* -- note that `std::cout` is only required to be a `std::ostrem` (output stream); it is not required to be a `std::ofstream` (output file stream). File streams tend to differ from `std::cout` in that they are usually not line buffered (streaming `'\n'` does not cause a flush) and in that they need not be tied to an input stream (see [`std::cout` @ cppreference.com](https://en.cppreference.com/w/cpp/io/cout)). A file stream *might* (not "must", but "might") delay all writing until program end, but that is much less likely for `std::cout`. – JaMiT Mar 14 '22 at 07:41

1 Answers1

3

The problem is in nl function. you have to pass ostream by reference. Have a look at this code

// Pass by Ref 
std::ostream& nl(std::ostream& os){
  os << '\n';
  return os;
}
zain ul din
  • 1
  • 1
  • 2
  • 23