Uri Blass wrote:Do you suggest that
setvbuf(stdout,NULL,_IONBF,0) can save the need for
fflush(stdout)?
Correct. Stetting to _IOLBF should even be sufficient, becaus the WB protocol is line orientated.
Uri Blass wrote:Even if this is correct I still do not understand the need for
setvbuf(stdin,NULL,_IONBF,0);
I use this, too. I actually only need it for Unix, not for Windows. As you know, detecting if input is available, is a bit tricky. There is no Standard C way, to do it. So we have to use system specific code. Under Windows for chess engine running under a GUI typically PeekNamedPipe is used. Under Unix we have the select() call which does something similar. But select() does not work with Standard C streams, it rather works with file handles (just integers). Instead of fopen() that returns a FILE *, there is the open() call, that returns a file handle. Things like fprintf() are not available for file handles. Also this lower level input/output system does not use any buffering.
stdin has the file handle 0 always. We can use select, to detect if the file handle of stdin has input. But now the following can happen:
Windows just sent "time 500\notim 500\n". You detect with select(), that input is available. However you use the Standard C function fgets() to read one line of input. What happens will be, when you call fgets() all input currently available (the two lines above) will be read into the internal stream buffer for stdin. You take one line out with fgets(). When you now call select again, it will return "no input available". Because that "otim 500\n" is already in the stream buffer.
When you set stdin to no buffered, there is no buffer for stdin, and "otim 500\n" would still stay available from the file handle of stdin, which select() would detect. And now everything works as expected.
It should actually work the same on Windows when using PeekNamedPipe, but for some reason it didn't for me. Therefore, in my input checking routine, I check stdin->_cnt under Windows (this is of course non portable, other environments will use other variables), which gives the number of bytes available in the stream buffer.
I am actually not sure, how unbuffered can work in general for input. Some Standard functions need to look ahead at least one byte. For example when you use fscanf(file, "%f", ...), it has to read on past the end of the number, to detect when the number ends (Assume input is "0.1enothing"). Only when you read the n of nothing, you detect that the number ended at "e". Also there is the fungetc() function.
Regards,
Dieter