如何在一段时间后停用输入语句?

我们知道输入函数或运算符(cin,scanf,get … .etc)等输入表单用户这次没有限制。

现在,我会问一个问题和用户给出答案,直到现在没有问题,但我的问题是“用户有时间(可能30或40秒)给出输入,如果他失败,那么输入语句将自动停用和执行下一个声明。“

我想你得到了我的问题。 那么请在这种情况下帮助我。 如果有人给我一些真正有用的示例代码会更好。

我在Windows 7中使用codebolck 12.11。

* IX’系统的方法(包括Windows上的Cygwin):

您可以使用alarm()来安排SIGALRM ,然后使用read(fileno(stdin), ...)

当信号到达时, read()将返回-1并将errnoEINTR

例:

 #define _POSIX_SOURCE 1 #include  #include  #include  #include  #include  #include  void handler_SIGALRM(int signo) { signo = 0; /* Get rid of warning "unused parameter 'signo'" (in a portable way). */ /* Do nothing. */ } int main() { /* Override SIGALRM's default handler, as the default handler might end the program. */ { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = handler_SIGALRM; if (-1 == sigaction(SIGALRM, &sa, NULL )) { perror("sigaction() failed"); exit(EXIT_FAILURE); } } alarm(2); /* Set alarm to occur in two seconds. */ { char buffer[16] = { 0 }; int result = read(fileno(stdin), buffer, sizeof(buffer) - 1); if (-1 == result) { if (EINTR != errno) { perror("read() failed"); exit(EXIT_FAILURE); } printf("Game over!\n"); } else { alarm(0); /* Switch of alarm. */ printf("You entered '%s'\n", buffer); } } return EXIT_SUCCESS; } 

注意:在上面的例子中, read()的阻塞调用将在任何到达的信号上中断。 避免这种情况的代码留给了读者…… 🙂

另一种方法:
您可以使用POSIX select()函数(以及一些宏FD_ZEROFD_SETFD_ISSET )来检查在给定时间间隔内哪些文件描述符(描述符编号0即stdin,在这种情况下)已准备好被读取。 准备好后,使用适当的函数读取数据(在这种情况下为scanf() )。
这段代码可能会帮助您理解,我想说的是:

 #include  #include  #include  #define STDIN 0 // Standard Input File Descriptor int main() { fd_set input; // declare a "file descriptor set" to hold all file descriptors you want to check int fds, ret_val, num; // fds: Number of file descriptors; struct timeval tv; // structure to store Timeout value in the format used by select() function unsigned int timeout = 5; // Your timeout period in seconds tv.tv_sec = timeout; tv.tv_usec = 0; fds = STDIN + 1; // Set number of file decriptors to "1 more than the greatest file descriptor" // Here, we are using only stdin which is equal to 0 FD_ZERO(&input); // Initialize the set with 0 FD_SET(STDIN, &input); // Add STDIN to set printf("Enter a number within %d secs\n", timeout); ret_val = select(fds, &input, NULL, NULL, &tv); // We need to call select only for monitoring the "input file descriptor set" // Pass rest of them as NULL if (ret_val == -1) // Some error occured perror("select()"); else if (ret_val > 0) // At least one of the file descriptor is ready to be read { // printf("Data is available now.\n"); if(FD_ISSET(0, &input)) // Check if stdin is set, here its not necessary as we are using STDIN only // So ret_val>0 means STDIN is raedy to read { scanf("%d", &num); } } else printf("No data within five seconds.\n"); // select returns zero on timeout return 0; } 

更多帮助: 选择(2)

您也可以尝试使用poll()函数(同样是POSIX标准函数)作为select()的替代方法。 见poll() & poll(2)

 #include  #include  #include  #include  bool get_input ( char *buffer, std::size_t size, int timeout ) { std::time_t start = std::time ( 0 ); std::size_t n = 0; for ( ; ; ) { if ( n == 0 && std::difftime ( std::time ( 0 ), start ) >= timeout ) return false; if ( kbhit() ) { if ( n == size - 1 ) break; char ch = (int)getche(); if ( ch == '\r' ) { buffer[n++] = '\n'; break; } else buffer[n++] = ch; } } buffer[n] = '\0'; return true; } int main() { char buffer[512] = {0}; if ( !get_input ( buffer, 512, 5 ) ) { std::cout<<"Input timed out\n"; buffer[0] = '\n'; } std::cout<<"input: \""<< buffer <<"\"\n"; }