How to deactivate input statement after some time?

2019-01-25 17:12发布

We know input function or operator (cin, scanf,gets….etc) wait to take input form user & this time has no limit.

Now, I will ask a question & user give the answer, till now there no problem but my problem is “user has a time(may 30 or 40 sec) to give the input, if he fail then input statement will automatically deactivated & execute next statement.”

I think you get my problem. Then please help me in this situation. It will be better if someone give me some really working example code.

I use codebolck 12.11 in windows 7.

标签: c++ c input cin
3条回答
够拽才男人
2楼-- · 2019-01-25 17:48

Another Method:
You can use POSIX select() function (and some macros FD_ZERO, FD_SET, FD_ISSET) to check which file descriptors (descriptor number 0 i.e. stdin, in this case) are ready to be read in a given time interval. When they are ready, use appropriate function to read the data (scanf() in this case).
This code might help you understand, what I want to say:

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

More Help: select(2)

You can also try using poll() function available in (again a POSIX standard function) as an alternative to select(). See poll() & poll(2)

查看更多
干净又极端
3楼-- · 2019-01-25 17:49
#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";
}
查看更多
够拽才男人
4楼-- · 2019-01-25 17:52

An approach for *IX'ish systems (including Cygwin on windows):

You could use alarm() to schedule a SIGALRM, then use read(fileno(stdin), ...).

When the signal arrives read() shall return with -1 and had set errno to EINTR.

Example:

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

Note: In the example above the blocking call to read() would be interupted on any signal arriving. The code to avoid this is left as an execise to the reader ... :-)

查看更多
登录 后发表回答