无等待命令接收input

可能重复:
C / C ++:从标准input中捕获字符而不必等待input被按下

char ch; 

想想我想要一个angular色。 我知道两种不同的方式。

1-在iostream头文件中使用cin命令。

 cin >> ch; 

它将等待用户键入内容,然后用户必须按回车键将input发送到chvariables。

在conio.h头文件中使用2- getch()命令。

 ch = _getch(); 

它将等待用户键入一些东西,只要input一个字符,它将被保存在variables中,用户不需要按回车键。 顺便说一句,这个代码将停止程序,并会等待input。

现在我想写一个不需要按下input的命令,它不会停止按下某个东西的程序。 试想一下,如果用户按下某些东西,它会将其保存到chvariables中,如果不是什么,程序将会继续,并且不会停止按下某个东西。 这就像是一个select器的命令,如果有东西会拿起它,如果没有,它将继续。

希望我清楚。 那么该怎么做呢?

首先我们需要一个打开和关闭非阻塞输入的函数:

 void nonblock(const bool state){ struct termios ttystate; //get the terminal state tcgetattr(STDIN_FILENO, &ttystate); if (state){ //turn off canonical mode ttystate.c_lflag &= ~ICANON; //minimum of number input read. ttystate.c_cc[VMIN] = 1; } else{ //turn on canonical mode ttystate.c_lflag |= ICANON; } //set the terminal attributes. tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); } 

现在我们需要一个函数来测试一个键是否被按下:

 int keypress(void){ struct timeval tv; fd_set fds; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); return FD_ISSET(STDIN_FILENO, &fds); } 

我们将同时检查两件事情。 用户是否按了一个键,或者有时间用完? 这是一个在指定的秒数之后更改布尔值的函数:

 void SleepForNumberOfSeconds(const int & numberofSeconds,bool & timesUp){ timespec delay = {numberofSeconds,0}; timespec delayrem; nanosleep(&delay, &delayrem); timesUp = true; return; } 

以下是您可以调用的主要功能:

 void WaitForTimeoutOrInterrupt(int const& numberofSeconds){ bool timesUp = false; std::thread t(SleepForNumberOfSeconds, numberofSeconds, std::ref(timesUp)); nonblock(1); while (!timesUp && !keypress()){ } if (t.joinable()){ t.detach(); } nonblock(0); return; } 

这是测试的代码 。
编译:

g ++ -std = c ++ 0x -o rand rand.cpp -lpthread

上:

gcc(Ubuntu / Linaro 4.6.1-9ubuntu3)4.6.1

这只是一个解决方案,它可能不适合你。
考虑到ncurses也是如此。

在Windows上,你可以这样做:

  1. CreateFile使用文件名"CONIN$" ,这将给你一个Win32句柄到控制台。
  2. WaitForSingleObject ,传递控制台句柄和超时。
  3. 如果等待成功,请使用ReadConsoleInput来确定发生了什么。
  4. 如果等待失败,则发生超时。

如果您只是在执行其他操作的循环中进行轮询,则可以使用PeekConsoleInput来检查输入队列中是否有事件,并且总是立即返回。


在Unix上,类似的方法将起作用。 请注意:

  1. 没有必要打开一个文件,因为stdin总是文件描述符0
  2. 使用selectpoll来测试输入上的活动是否超时。

最后的区别:在Windows上,以相同的方式捕获鼠标活动。 在Unix上,你通常会从tty读取键盘输入,而鼠标是完全独立的。