C stdout to stdin in real time

I have two programs, one of which is called a generator, which prints text per second

int main(int argc, char** argv) { for(int i = 0; i < 10 ; i++) { printf("something\n"); sleep(1); } return (EXIT_SUCCESS); } 

then a has a second program that calls it a consumer, which should read from standard input, add some other text to it and retype it. Let it look like this:

  int main(int argc, char** argv) { char line[BUFSIZ]; while(scanf("%s",line) != -1){ printf("you entered %s \n",line); } return (EXIT_SUCCESS); } 

when I compile them and try to run only a type generator. / generator, it works as I expected. every second something prints to the console. but when I try to run them like. / generator | ./consumer it did not work as I expected. I wait 10 seconds, and after that I get 10 lines that you entered something. I want to print "you entered something" every second.

Can you explain to me why this is so, or is it even better to tell me how to achieve the expected behavior?

+5
source share
4 answers

CI / O are buffered. When using terminal inputs / outputs, the buffer discipline line is buffered , so the contents are output when \n sent. When you use pipes, the buffering discipline is filled with a buffer , so the contents are cleared only when the buffer is full (regardless of the contents).

You can:

  • flush(stdout) every time you need really real data,
  • change the buffer discipline to setvbuf before any entry.
+4
source

The output from your printf is buffered and only output when the buffer is full. You can call setbuf () on the consumer (once at the beginning) with NULL as the second argument to set the buffer size on stdout to NULL.

 #include <stdio.h> setbuf( stdout, NULL ); 

This will lead to the immediate output of the output written to standard output (i.e. your printf). Alternatively, you can write stderr, which defaults to the size of a NULL buffer. (Or, as another alternative, you can call fflush on stdout every time you want to flush the contents of the buffer to the terminal).

+3
source

The output is buffered, so the stdio library waits until it has a bunch of data, usually 4 kilobytes, and then comes out right away.

Just add the fflush call whenever you want the output to actually be output:

 fflush(stdout); 

It works differently when output is sent directly to the terminal. Standard output is then buffered by line, so the buffer will turn red after each character at the end of the line.

+2
source

You should use threads to execute parts of your program in parallel:

 #include <iostream> #include <thread> #include <unistd.h> using namespace std; void Print() { sleep(1); cout << "Thread trolling you!!!\n"; Print(); } int main () { string g; thread ttt(Print); //create thread, from now Print() runs parallel to cin >> g; //the rest of int main() cout << g; ttt.join(); //join threads return (0); } 
-3
source

Source: https://habr.com/ru/post/1259295/


All Articles