Exits the loop after a certain amount of time if there's no input

后端 未结 3 1374
南方客
南方客 2021-01-19 03:22

I\'m just wondering whether is it possible and how do I implement this feature, where we exit from the loop if there\'s no input from the user. For example, I want to exit t

相关标签:
3条回答
  • 2021-01-19 03:42

    Use select() function to set a timeout for your scanf

    The following code is an example of how use it.

    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/time.h>
    
    int main(void)
    {
        int x;
        fd_set          set;
        struct          timeval timeout = {0};
    
        FD_ZERO(&set);
    
    
       while(1)
       {
            timeout.tv_sec = 30;
            FD_SET(fileno( stdin ), &set);
            printf ("enter a number:");
            fflush (stdout);
            if (select(FD_SETSIZE, &set, NULL, NULL, &timeout))
            {
    
               scanf("%d", &x);
               printf("The number you put is %d\r\n",x);
    
            }
            else
            {
                    printf("\r\nTimeout: Stop reading\r\n");
                    break;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-19 03:51

    This task is usually done using threads. In one thread getchar is called which blocks the thread execution, another thread does sleep() and then kills the first thread.

    Another way to do this is to use non-blocking read() from the standard input using pselect (2), but it's more tricky and does not suit small applications well.

    Though a solution with pthreads in unix-style is quite verbose:

    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    #include <pthread.h>
    
    struct read_int {
        int success;
        int value;
        struct timespec timeout;
    };
    
    void* read_thread(void *arg) {
        struct read_int *s = arg;
        printf("Enter a number: ");
        scanf("%d", &s->value);
        s->success = 1;
        return NULL;
    }
    
    #define CHECK_RET(ret, func) \
        if (ret) { fprintf(stderr, func"() == %d\n", ret); return ret; }
    
    int main() {
        pthread_t rthr;
        pthread_attr_t thr_attr;
    
        struct read_int s = { 0 };
        int ret;
    
        ret = clock_gettime(CLOCK_REALTIME, &s.timeout);
        if (ret == -1) { fprintf(stderr, "clock_gettime() == %d\n", ret);  return ret; }
    
        s.timeout.tv_sec += 5;
    
        ret = pthread_attr_init(&thr_attr);
        CHECK_RET(ret, "pthread_attr_init");
    
        ret = pthread_create(&rthr, &thr_attr, read_thread, &s);
        CHECK_RET(ret, "pthread_create");
    
        ret = pthread_attr_destroy(&thr_attr);
        CHECK_RET(ret, "pthread_attr_destroy");
    
        pthread_timedjoin_np(rthr, NULL, &s.timeout);
    
        if (s.success) {
            printf("\ngot value %d\n", s.value);
        } else {
            pthread_cancel(rthr);
            printf("\nTimed out, exiting...\n\n");
        }
    }
    
    0 讨论(0)
  • 2021-01-19 04:08

    Although the time_t structure returned by time() is most likely a number of seconds, you should not be performing maths on it. Instead use difftime()

    double difftime ( time_t time2, time_t time1 );
    

    Calculates the difference in seconds between time1 and time2.

    You do not need to call main() from within main() and I'm not sure why you would think that is a good idea.

    Also, getchar() will wait for a key to be pressed, so it won't be counting time in the background.

    0 讨论(0)
提交回复
热议问题