How to deactivate input statement after some time?

后端 未结 3 1877
夕颜
夕颜 2020-12-18 08:02

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 a

相关标签:
3条回答
  • 2020-12-18 08:23

    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)

    0 讨论(0)
  • 2020-12-18 08:24

    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 ... :-)

    0 讨论(0)
  • 2020-12-18 08:45
    #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";
    }
    
    0 讨论(0)
提交回复
热议问题