7 个回答
一般来说,用scanf就得用多线程;不用scanf、非阻塞读取键盘缓冲区就不需要多线程。
当然,你也可以用select反复等待stdin可读,当select返回,就说明用户输入了信息,此时调用getch可以立即返回,不会造成阻塞。
但此时scanf行为可能受stdin缓冲模式(比如是遇到回车才返回可读还是敲一个字符就返回可读)以及scanf本身期望的模式字符串影响(比如用户敲了一个字符,你的scanf却期望他输入一个数字、一个逗号、另一个数字,回车;那么这时候肯定还是要卡住了)——总之,较为复杂的程序很少用scanf,因为它太机械了,和它设想的状况有一点点差异都会搅乱你的逻辑。
然后,需要每隔1s显示数字也很简单,select超时设置为1s就行了。
注意,你要检查select返回信息,确认真正的原因;具体可参考相关文档。
如果select返回原因是超时,那就dispatch到时间显示处理函数;如果返回原因是stdin可读,就dispatch到字符读取处理函数——注意此时在getch之后、重新调用select时要扣除上次显示输出到现在已经流逝的时间,否则时间间隔就不正确了。
当然,如果你搞正式项目的话,可以考虑著名的ncurses文本界面库。它直接内置了一整套机制,你自己就不用操心很多细节问题了。