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

时间:2013-08-17 14:01:05

标签: c++ c input cin

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

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

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

我在Windows 7中使用codebolck 12.11。

3 个答案:

答案 0 :(得分:10)

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

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

当信号到达时read()将返回-1并将errno设置为EINTR

示例:

#define _POSIX_SOURCE 1

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

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()的阻止呼叫将在任何信号到达时中断。避免这种情况的代码留给读者......: - )

答案 1 :(得分:2)

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

#include <sys/select.h>
#include <sys/time.h>
#include <stdio.h>

#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;
}

更多帮助:   select(2)

您也可以尝试使用(再次作为POSIX标准函数)中的poll()函数作为select()的替代方法。见poll()&amp; poll(2)

答案 2 :(得分:0)

#include <cstddef>
#include <ctime>
#include <iostream>
#include <conio.h>

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";
}