Making stdin non-blocking

后端 未结 4 1103
情深已故
情深已故 2020-12-18 07:37

I have an exercise where I am required to print a file slowly (1 second intervals) until the file ends, unless the user types a character.

So far, the program output

4条回答
  •  有刺的猬
    2020-12-18 08:19

    This is a working version, using tcgetattr/tcsetattr:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(void) {
        FILE* infile;
        char str[100];
        fd_set readset;
        struct timeval tv;
        struct termios ttystate, ttysave;
    
        // open a file
        if((infile = fopen("infile", "r")) == NULL)
        {
            (void)printf("Couldn't open the file\n");
            exit(1);
        }
        // file was opened successfully
    
        //get the terminal state
        tcgetattr(STDIN_FILENO, &ttystate);
        ttysave = ttystate;
        //turn off canonical mode and echo
        ttystate.c_lflag &= ~(ICANON | ECHO);
        //minimum of number input read.
        ttystate.c_cc[VMIN] = 1;
    
        //set the terminal attributes.
        tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
    
        // while we are not at the end of a file
        while(fgets (str, 100, infile))
        {
            // set the time value to 1 second
            tv.tv_sec = 1;
            tv.tv_usec = 0;
    
            FD_ZERO(&readset);
            FD_SET(fileno(stdin), &readset);
    
            select(fileno(stdin)+1, &readset, NULL, NULL, &tv);
            // the user typed a character so exit
            if(FD_ISSET(fileno(stdin), &readset))
            {
                fgetc (stdin); // discard character
                break;
            }
            // the user didn't type a character so print the next line
            else
            {
                puts(str);
                // not needed: sleep(1);
            }
        }
    
        // clean up
        fclose(infile);
    
        ttystate.c_lflag |= ICANON | ECHO;
        //set the terminal attributes.
        tcsetattr(STDIN_FILENO, TCSANOW, &ttysave);
        // report success
        return 0;
    }
    

    The sleep(1); isn't needed anymore.

提交回复
热议问题