breaking loop with keypress in linux c

假装没事ソ 提交于 2019-12-14 03:52:03

问题


I need to write a program in C language which will be doing something like this: For example, when I will press "a", terminal will be writing that typed character in the unending loop like this: aaaaaaaaaaaaaaaa...until another key, for example "b" will be pressed. Final output should look like this: aaaaaaaaabbbbbbq (q should terminate the program). My code here:

int main(int argc, char** argv) {

    int c;
    static struct termios staryTermios, novyTermios;


    tcgetattr(STDIN_FILENO, &staryTermios);

    novyTermios = staryTermios;
    novyTermios.c_lflag &= ~(ICANON);
    tcsetattr(STDIN_FILENO, TCSANOW, &novyTermios);
    while ((c = getchar()) != 'q') {
        putchar(c);
    }

    tcsetattr( STDIN_FILENO, TCSANOW, &staryTermios);

    return 0;
}

this version writes the typed characters only once and then it waits for another keypress


回答1:


I guess you will need two threads which will both be accessing a common variable. The job of one thread would be to continuously print the common variable. The job of the second would be to wait for input from the keyboard and update the variable accordingly.




回答2:


To achieve the result you want, you need to make the standard input non-blocking. You can do that with this minor adaptation of your code. It worked fine on Mac OS X 10.7.5. Note that getchar() returns EOF when there's no character ready to read (which will be most of the time; neither you nor I can type fast enough to matter to a modern computer). I'm mildly concerned that on some systems, once getchar() has returned EOF once when there was no character to read, it might never return anything other than EOF again, but that wasn't a problem for Mac OS X.

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

static void err_exit(const char *msg);

int main(void)
{
    int c;
    int oc = '\0';
    struct termios staryTermios, novyTermios;
    int oflags, nflags;

    if (tcgetattr(STDIN_FILENO, &staryTermios) != 0)
        err_exit("tcgetattr() failed");

    novyTermios = staryTermios;
    novyTermios.c_lflag &= ~(ICANON);
    if (tcsetattr(STDIN_FILENO, TCSANOW, &novyTermios) != 0)
        err_exit("tcsetattr() failed to set standard input");

    oflags = fcntl(STDIN_FILENO, F_GETFL);
    if (oflags < 0)
        err_exit("fcntl() F_GETFL failed");

    nflags = oflags;
    nflags |= O_NONBLOCK;
    if (fcntl(STDIN_FILENO, F_SETFL, nflags) == -1)
        err_exit("fcntl() F_SETFL failed");

    while ((c = getchar()) != 'q')
    {
        if (c != EOF)
            oc = c;
        if (oc != '\0')
            putchar(oc);
    }

    if (tcsetattr(STDIN_FILENO, TCSANOW, &staryTermios) != 0)
        err_exit("tcsetattr() failed to reset standard input");

    putchar('\n');
    return 0;
}

static void err_exit(const char *msg)
{
    fprintf(stderr, "%s\n", msg);
    exit(1);
}


来源:https://stackoverflow.com/questions/15310848/breaking-loop-with-keypress-in-linux-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!