c++ stream buffer and flush - c++

#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono;
int main() {
std::cout << "hello";
std::this_thread::sleep_for(2s);
std::cout << "world"<<std::endl;
}
I m using visual studio 2019.
I expect above code to print helloworld after 2 seconds but hello is displayed before 2 seconds in the console(i.e instantly when i run the program) and world is displayed after 2 seconds.
I read about buffer recently and came to know that the text should be displayed in the console only after the buffer is full.
We can force to flush the buffer by using \n, manupulators and cin.
But why am I not seeing desired behavior in this particular example?
Isn't cout using buffer?
Is it flushed for every character?

There is no strict rule in the standard when a buffer should be flushed.
Like #Yksisarvinen mentioned in the comments, a flush isn't affected by the compiler but by the operating system. Also \n doesn't always trigger a flush. If the cout is going to a terminal, it is usually line buffered, thus you can force a flush via \n.
More information can be found at:
When does cout flush?
and
Does new line character also flush the buffer?

Related

C++: getline freezes at end of file

I want to read in one file line-by-line and output each line I read to a new file. In this code, cin has been redirected to refer to the input file, and cout has been redirected to refer to the output file.
The loop successfully writes every line in the file, but then it gets stuck on the final getline call. As a result, "Done" is not written to the file and the program does not terminate.
#include <string>
#include <iostream>
using namespace std;
int main() {
string line;
while(getline(cin, line)) {
cout << line << endl;
}
cout << "Done";
return 0;
}
Strangely, if I forcibly terminate the program, it seems to suddenly execute as desired, with "Done" being written.
Can someone point me in the right direction? Is there a flaw in the code, or is this some external configuration issue?
Notes: The input file in question ends with a newline character. Also, I do not want to use any includes besides these two.
The code should terminate on end of file (EOF) or any sort of file error. (The getline being called is:
http://en.cppreference.com/w/cpp/string/basic_string/getline
It returns the cin istream and then invokes its boolean conversion operator:
http://www.cplusplus.com/reference/ios/ios/operator_bool/
that checks if badbit or failbit is set on the stream. The failbit state should be set when a read is attempted with the stream already at EOF, or if there is an error.)
Per the comments above, it seems like this does work when the code is run from the shell directly. My guess is Eclipse is doing something complicated where it either intentionally sends the file into the program and then switches to an interactive input mode, or has a bug in which it doesn't close its end of a pipe or pty/tty it is using to send input to the program. (I.e. Eclipse is not binding stdin directly to the file itself in running the program.)
If one wanted to debug it further, one could look at the process state using tools like lsof. (Assuming a UNIXy system.) Might also be worth raising the issue in an Eclipse forum. The IDE is not my area of expertise.

WriteFile function with assembly debugging (syncing)

First of all, this question is based on my last question here: Reading Console Buffer / Output C++
I have a compiled executable binary file. It has some outputs, what I would like to redirect it to an other program, that handles the lines. I successfully found where the output is sent, and I modified it to STDOUT. The problem is that, when I use it like:
./jampDed.exe | stdout.exe
then the output is not synced. I got the content after every 1000-2000 bytes.
stdout.cpp
#include <iostream>
int main() {
std::string s;
while (std::getline(std::cin, s, '\n')) {
std::cout << s << std::endl;
}
return 0;
}
I also created a picture about assembly modification, where Kernel32.WriteFile function was used by default.
So the question is that, how can I make it synced? How to get every line as soon as it happens on the dedicated server?
Somewhere in the executable where it establishes stdout is an option bit for unbuffered output. Just set (or clear) that bit. Then every call to write is transferred without delay. This adds significant execution time and i/o system effort to that program but is probably okay for this.
The program which processes that output (as input) should buffer full lines because the program is unlikely to do full line output itself.
Why don't you try:
std::cout << s << std::endl << std::flush;
^^^^^^^^^^

Considering the C++ program below, what should be inserted in place of //***** to ensure a 100% clean shutdown?

This is an exam question:
Considering the C++ program below, what should be inserted in place of
//***** to ensure a 100% clean shutdown?
#include <iostream>
#include <fstream>
int main(int argc, char* argv[])
{
using namespace std;
fstream log("log.txt", ios::out);
streambuf* clog_buf = clog.rdbuf(log.rdbuf());
clog << "Test the logger" << endl;
//*****
}
A. Nothing is missing.
B. exit();
C. clog.rdbuf(clog_buf);
D. clog.rdbuf(0);
E. log.rdbuf(0);
I am rather confused on the use of log and clog in this code. Why can't we just create a file and write down everything we need? Any explanation would be appreciated.
clog_buf points to the stream buffer that clog pointed to before you reset it with rdbuf. A clean shutdown can be achieved by resetting clog's stream buffer to what it was before by using C ( clog.rdbuf( clog_buf ); ).
The code is swapping the standard clog stream (which initially works on STDERR) for a file stream. It means that any code anywhere in the program that streams to clog will actually now stream to a file instead. It's a good localised way to redirect log output, which doesn't require search/replacing ten million utterances of the text clog in your source code.
The answer is C, which reverts the clog stream back to the way you found it before the implicit return 0 kicks in and the program ends gracefully, including the normal file stream destruction.
exit() is a non-graceful shutdown which would not close your file stream properly.
This code does not appear to be exception safe.
Therefore, in the face of exceptions, none of the answers will ensure a 100% clean shutdown.

Get permanently the output from a shell command running in C++

I want to get the output from a shell command (my_program). Here is a example taken from this site:
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
FILE *in;
char buff[512];
if(!(in = popen("my_program", "r"))){
return 1;
}
while(fgets(buff, sizeof(buff), in)!=NULL){
cout << buff;
}
pclose(in);
return 0;
}
The problem:
I want to run my program permanently and get the output while the program is still running, NOT only get the output from the program once.
Any idea?
Your question is somewhat unclear but I suspect that the problem is buffer and the answer flushing: The way I understand is the program my_program produced outputs occassionally and the program you show should kick into action when my_program prints something. Further I suspect that this program doesn't produce a lot of output in total, e.g. less than 4k.
The problem is that most implementations buffer standard output differently depending of whether this is directed to a "console" or something else: when writing to the console output tends to be line-buffer while other destinations buffer substantially bigger buffers. However, the buffer can be explicitly flushed, reducing the performance of the output substantially. Of course, in the scenario above you'd be more interest in timely outputs rather than output performance.
A simple approach to flush an output buffer in C++ us to use out << std::flush. If you quickly want to verify that this the problem you can set up the stream to flush after every output operation using out << std::unitbuf. There are a number of other approaches to automatically flush but these are a bit more involved.

ofstream doesn't flush

I have the following code, running on Suse 10.1 / G++ 4.1.0, and it doesn't write to the file:
#include <fstream>
#include <iostream>
int main(){
std::ofstream file("file.out");
file << "Hello world";
}
The file is correctly created and opened, but is empty.
If I change the code to:
#include <fstream>
#include <iostream>
int main(){
std::ofstream file("file.out");
file << "Hello world\n";
}
(add a \n to the text), it works.
I also tried flushing the ofstream, but it didn't work.
Any suggestions?
If you check your file doing a cat , it may be your shell that is wrongly configured and does not print the line if there is no end of line.
std::endl adds a \n and flush.
Don't know if this is what you tried but you should do:
file << "Hello World" << std::flush;
Update; I'm leaving this answer here because of the useful comments
Based on feedback, I'll modify my advice: you shouldn't have to explicitly call std::flush (or file.close() for that matter), because the destructor does it for you.
Additionally, calling flush explicitly forces an I/O operation that may not be the most optimized way. Deferring to the underlying iostreams and operating system would be better.
Obviously the OP's issue was not related to calling or not calling std::flush, and was probably due to attempting to read the file before the file stream destructor was called.
The destructor should flush and close the file.
I am pretty sure, the error is an another place, either
1) You do not check at the right point in time. At which point do you compare the content of the file, "after" the exits, or do you set a breakpoint before the program exits and then you check the files content?
2) Somehow the program crashes before it exits?
Does
file << "Hello world" << std::endl;
work?
endl inserts a newline and flushes the buffer. Is that what you were referring to when you said that you'd already tried flushing it?
You are working on Linux, which is a POSIX-compliant system. The POSIX standard defines what a line is:
A sequence of zero or more non-newline characters plus a
terminating newline character.
So without the newline character, the file contains 0 lines and is therefore empty.