Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
589 views
in Technique[技术] by (71.8m points)

c - How can I prevent scanf() to wait forever for an input character?

I want to fulfill the following things in a console application:

  1. If user inputs a character, the application will do the corresponding task. For example, if user inputs 1, the program will do task 1, if user inputs q, the program will quit;
  2. If user inputs nothing, the program will do the default task every 10 seconds (the time needn't to be very strict).

Here is my code:

#include <stdio.h>
#include <time.h>

char buff[64];
char command;

while(command != 'q')
{
   begin:
   printf(">> ");
   scanf("%s", buff);
   command = buff[0];

   switch (command)
   {
       case '1':
       // task 1 code will be added here;
          break;
       case '2':
       // task 2 code will be added here;
          break;
       case 'q':
          printf("quit the loop.
");
          break;
   }

   // wait for 10 seconds;
   Sleep(10000);
   // default task code will be added here;

  if(command != 'q')
  {
     goto begin;
  }

}

But the problem is the program will trap at the line of scanf() function forever to wait for an input character, if no character is entered. So I'm wondering how to skip the line of scanf() after a certain time, I mean for example, if no input after 1 second, the program can continue, so as to fulfill the second thing listed above.

The platform is Windows, if it matters.

I've removed the semicolon after the while() it was an obvious mistake.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try using the select() function. Then you can wait for 10 seconds until you can read from stdin without blocking. If select() returns with zero, perform the default action. I don't know if this works on windows, it's POSIX standard. If you happen to develop on unix/linux, try man select

I just wrote a working example using select:

#include <stdlib.h>
#include <stdio.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define MAXBYTES 80

int main(int argc, char *argv[])
{
        fd_set readfds;
        int    num_readable;
        struct timeval tv;
        int    num_bytes;
        char   buf[MAXBYTES];
        int    fd_stdin;

        fd_stdin = fileno(stdin);

        while(1) {
                FD_ZERO(&readfds);
                FD_SET(fileno(stdin), &readfds);

                tv.tv_sec = 10;
                tv.tv_usec = 0;

                printf("Enter command: ");
                fflush(stdout);
                num_readable = select(fd_stdin + 1, &readfds, NULL, NULL, &tv);
                if (num_readable == -1) {
                        fprintf(stderr, "
Error in select : %s
", strerror(errno));
                        exit(1);
                }
                if (num_readable == 0) {
                        printf("
Performing default action after 10 seconds
");
                        break;  /* since I don't want to test forever */
                } else {
                        num_bytes = read(fd_stdin, buf, MAXBYTES);
                        if (num_bytes < 0) {
                                fprintf(stderr, "
Error on read : %s
", strerror(errno));
                                exit(1);
                        }
                        /* process command, maybe by sscanf */
                        printf("
Read %d bytes
", num_bytes);
                        break; /* to terminate loop, since I don't process anything */
                }
        }

        return 0;
}

Note: the poll() example below is OK too, no problem. For the rest I chose to read the available bytes into a buffer (up to MAXBYTES). It can be (s)scanned afterwards. (scanf() just isn't too much my friend, but that's a personal taste matter).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...