0

The following code gets TLE (time limit exceeded) if the standard output is not flushed.

#include<stdio.h>
int main(){
    int a;
    while(1){
        scanf("%d",&a);
        printf("%d\n",a);
        fflush(stdout);
        if(a==42)
            break;
    }
    return 0;
}

How does flushing the output buffer help to overcome TLE?
This is the problem link - https://www.spoj.com/problems/EXPECT/

Imtiaz
  • 25
  • 2
  • 7

1 Answers1

5

The problem specification tells you what to do:

Attention: the program should clear the output buffer after printing each line.

It can be done using fflush(stdout) command or by setting the proper type of buffering at the beginning of the execution - setlinebuf(stdout).

The problem title indicates why:

(Interactive)

The judging software is operating the program interactively. After giving the program an input, it waits for output before providing more input. When your program does not flush the buffered output, the judging software keeps waiting until its time limit is exceeded.

Commonly, output streams to terminals are line-buffered, in which case printing a new-line character causes them to be flushed. However, this judging software is likely using a pipe that is fully buffered, so output will not be flushed until the buffer is full or you explicitly request a flush (or, at the start of the program, you change the buffering mode to unbuffered or line-buffered).

When you flush the output, the judging software will see it, and then it will continue and provide more input.

As an alternative to flushing the output after each printf, you can set the stream to line buffering mode by executing setvbuf(stdout, NULL, _IOLBF, 0); at the beginning of the program (before doing any other operation on the stream).

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • So, in other programs the output stream is flushed automatically. But in this program, it is not happening automatically and it is getting time limit exceeded. – Imtiaz Mar 01 '21 at 15:58
  • 1
    @MukaddasImtiazHimel: It is not about the program. It is about where the output stream goes. When a program is starting, buffering is configured for the standard output stream. Per C 2018 7.21.3 7 “As initially opened,… the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.” Thus, if the startup code can see the output is going to a terminal, the output is not fully buffered (is unbuffered or line buffered). If it can see the output is going to a pipe, the output is fully buffered. – Eric Postpischil Mar 01 '21 at 16:07
  • So, this judging software is using pipe which is fully buffered and that's why it needs to be flushed or program will get time limit exceeded. Otherwise the output stream will be line buffered and it doesn't require flushing. – Imtiaz Mar 01 '21 at 16:17
  • I liked the answer but just few little questions. What could be the size of buffer?How much data does it take to get full? – Akash Dahane Mar 02 '21 at 10:02
  • 2
    @AkashDahane: You can see the size of the buffer by running this program: `#include ` / `int main(void) { for (int i = 0; i < 16384; ++i) { fprintf(stderr, "%d\n", i); putchar('*'); } }`. It writes one character at a time to `stdout`, after writing how many bytes it has written so far to `stderr`. Since the `stderr` output includes `\n`, it will be flushed in each call. When the `stdout` buffer is full, it will be flushed and will appear immediately after the number of bytes that have been written to it. That number is the size of the buffer. – Eric Postpischil Mar 03 '21 at 19:17
  • @AkashDahane: The program is set to write 16,384 lines. You might want to direct its output to a file to capture them, in case your terminal window’s buffer does not keep that many. 4096 bytes might be a typical buffer size these days. It could vary depending on circumstances; I do not know. – Eric Postpischil Mar 03 '21 at 19:18