如何通过从键盘获取任何值来打破Linux上的C循环?

nit*_*h.s 5 c linux while-loop

我正在构建的程序在无限循环中运行,其中包含一个开关盒.我想在每种情况下插入一个while循环并在循环中执行一些操作,但是一旦给出键盘输入,循环就应该退出.因此,在从键盘获取输入之后,另一个案例在其中嵌套了while循环,并且该过程继续.

结构是:

while()//infinite loop
    {
    ...............      //operations
    ...............      //operations
    switch()
        {
        case 1:
        ...............    //operations
        ...............    //operations
        while()//infinite loop
             {
             ..............
             ..............
             exit if there is any input from keyboard
             }
        break;

        case 2:
        ...............    //operations
        ...............    //operations
        while()//infinite loop
             {
             ..............
             ..............
             exit if there is any input from keyboard
             }
        break;


        case n:
        ...............    //operations
        ...............    //operations
        while()//infinite loop
             {
             ..............
             ..............
             exit if there is any input from keyboard
             }
        break;
        }
  }
Run Code Online (Sandbox Code Playgroud)

有什么办法吗???

Rin*_*g Ø 6

Linux键盘输入是缓冲的,为了捕获动态命中的密钥,您必须配置TERM IO.

main()顶部附近添加一个调用(参见下面的代码)

term_nonblocking();
Run Code Online (Sandbox Code Playgroud)

读取即时按下的键,而不等待回车(CR).

码:

struct termios stdin_orig;  // Structure to save parameters

void term_reset() {
        tcsetattr(STDIN_FILENO,TCSANOW,&stdin_orig);
        tcsetattr(STDIN_FILENO,TCSAFLUSH,&stdin_orig);
}

void term_nonblocking() {
        struct termios newt;
        tcgetattr(STDIN_FILENO, &stdin_orig);
        fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // non-blocking
        newt = stdin_orig;
        newt.c_lflag &= ~(ICANON | ECHO);
        tcsetattr(STDIN_FILENO, TCSANOW, &newt);

        atexit(term_reset);
}
Run Code Online (Sandbox Code Playgroud)

注意:term_reset()程序退出时会自动调用(重置终端参数).

您可以getchar()在程序中的任何位置调用现在的非阻塞来检测按键

int i = getchar();
Run Code Online (Sandbox Code Playgroud)

并检查是否按下了某个键:

if (i > 0) {
    // key was pressed, code in `i`
}
Run Code Online (Sandbox Code Playgroud)

在您的程序中,例如:

int key = 0;

while (... && key <= 0) {
   // ... 
   key = getchar();
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您希望输出无缓冲,请调用setbuf(stdout, NULL);

(来自@stacey的注释:当没有密钥可用时,getchar()可能返回0或-1)


nit*_*h.s 0

谢谢大家……尽管我的回答有点不合常理,但我认为ring0的方法要好得多。这就是我所做的。

  • 在外部 while 循环内添加了代码,允许编译器从文件(例如 data.dat)中获取 switch case 的参数
  • 在每个嵌套 while 循环中添加类似的代码,如果从 data.dat 检索到的变量是运行循环所需的变量,则继续,如果不是,则中断。
  • 由于在linux中我可以在后台运行进程,因此我在后台运行主程序,并相应地编辑data.dat。

这个方法对我有用,但肯定也会尝试ring0的方法。