C 我还没有在课堂上创建多个线程,所以我想我的教授希望我们用另一种方法来实现这一点。这个程序对我来说仍然运行相同的程序。不过谢谢你的输入。这个程序的运行方式正是我所期望的。非常感谢你的回答。不幸的是,我们从未讨论过termios标题,所以我认为我的教授有不同的

C 我还没有在课堂上创建多个线程,所以我想我的教授希望我们用另一种方法来实现这一点。这个程序对我来说仍然运行相同的程序。不过谢谢你的输入。这个程序的运行方式正是我所期望的。非常感谢你的回答。不幸的是,我们从未讨论过termios标题,所以我认为我的教授有不同的,c,C,我还没有在课堂上创建多个线程,所以我想我的教授希望我们用另一种方法来实现这一点。这个程序对我来说仍然运行相同的程序。不过谢谢你的输入。这个程序的运行方式正是我所期望的。非常感谢你的回答。不幸的是,我们从未讨论过termios标题,所以我认为我的教授有不同的答案。再次感谢您的努力。@MJPiarulli:告诉您的教授您领先于时代。在本例中,您使用ttysave做什么?@AlexReinking终端在程序退出后仍将被更改。因此,最好修改示例以恢复ttysave使用选择,您不必反复检查按键select


我还没有在课堂上创建多个线程,所以我想我的教授希望我们用另一种方法来实现这一点。这个程序对我来说仍然运行相同的程序。不过谢谢你的输入。这个程序的运行方式正是我所期望的。非常感谢你的回答。不幸的是,我们从未讨论过termios标题,所以我认为我的教授有不同的答案。再次感谢您的努力。@MJPiarulli:告诉您的教授您领先于时代。在本例中,您使用
ttysave
做什么?@AlexReinking终端在程序退出后仍将被更改。因此,最好修改示例以恢复ttysave使用
选择
,您不必反复检查按键
select
可以同时休眠和等待输入。我确实意识到终端正在缓冲行,因此我的字符位于换行符之前。但是,我没有意识到select()在Linux上的实现方式有所不同。我已经做了建议的更改,程序仍在运行。即使当我输入一个字符并按enter键时,终端也会切入并告诉我:命令找不到。@MJPiarulli:如果您的输入没有被程序使用(例如,使用
read
fgets
),它将被终端读取。
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
    FILE* infile;
    char str[100];
    fd_set readset;
    struct timeval tv;

    // open a file
    if((infile = fopen("infile", "r")) == NULL)
    {
        (void)printf("Couldn't open the file\n");
        exit(1);
    }
    // file was opened successfully
    else
    {       
        // while we are not at the end of a file
        while(fgets(str, 100, infile) != NULL)
        {
            FD_ZERO(&readset);
            FD_SET(fileno(stdin), &readset);
            // set the time value to 1 second
            tv.tv_sec = 1;
            tv.tv_usec = 0;
            select(fileno(infile)+1, &readset, NULL, NULL, &tv);
            // the user typed a character so exit
            if(FD_ISSET(fileno(stdin), &readset))
            {
                fclose(infile);
                exit(0);
            }
            // the user didn't type a character so print the next line
            else
            {
                fgets(str, 100, stdin);
                puts(str);
            }
        }

        // clean up
        fclose(infile);
    }

    // report success
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

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;
}
// set the time value to 1 second
tv.tv_sec = 1;
tv.tv_usec = 0;