如何在绝对标准的C编译器和系统(比如DOS)写出无阻塞输入
一般来说,无阻塞输入指在输入时,接收输入的程序可以执行其他操作,不会等待或有固定等待时间,比如玩游戏时,哪怕你没按任何键,敌人也会动,一般而言,用C标准库做这样的输入几乎不可能,但是我们看看:在用户没有输入时,程序要知道用户没输入,也就不移动玩家,再考虑NPC,所以我们只需让程序知道用户没按键,但输入就会卡住程序,读到输入就返回,能不能卡一个输入流的BUG呢?
你看,虽然C默认IO先存在缓冲区,但在取消缓冲区后,输入流也可看作缓冲区,因为不调用输入函数,输入流里的东西不会直接被读,但是只要调用一次,就立刻会被读取,除非里面没东西,输入函数会等待。
虽然输入流里的东西来自键盘或命令行,但也不是不能写进去,比如stdio.h里的ungetc(),该函数会将作为其中一个参数的字符写进缓冲区,该字符会被优先读取,除非在读取前有输入,看懂了吗?如果在读取前将一个一般用户无法输在命令行的字符写入输入流,读的时候,如果返回这个字,说明用户没按任何键;若不返回这个字而是其他字,说明用户键入了(重定向不算),如此,至少解决了阻塞输入卡住的问题,因为每一次都会读一个字符。
由于我们规定系统是绝对标准的,所以使用setvbuf(stdin,NULL,_IONBF,0);后应保证取消缓冲区,而linux发行版在该调用后不会取消命令行缓冲区,所以请修改相关设置。
代码示例:
#include <stdio.h>
int nbfin(void){
char a;
setvbuf(stdin,NULL,_IONBF,0);
ungetc(‘\0’,stdin);
a=getchar();
if(a==‘\0’)
return -2;
return a;
}
