Неблокирующий ввод клавиатуры в c [дубликат]

SELECT * FROM emp a
WHERE  n = (SELECT COUNT( _rowid)
              FROM emp b
             WHERE a. _rowid >= b. _rowid);
2
задан Ikki 18 April 2015 в 21:51
поделиться

3 ответа

На MAC-адресе вам нужно поиграть с настройками терминала, чтобы отключить буферизацию строк. (Вы также можете отключить эхо.) Как только терминал настроен правильно, вы можете использовать read для получения отдельных символов с клавиатуры.

В приведенном ниже примере кода функция kbsetup выполняет настройки терминала. Функция getkey проверяет нажатие клавиши и возвращает ключ, если таковой имеется, или '\0', если никакая клавиша не была прочитана. Функция main имеет цикл, который печатает время один раз в секунду и печатает любую клавишу, которую пользователь нажимает. Нажмите 'q', чтобы выйти из программы.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <termios.h>
#include <unistd.h>

static struct termios oldSettings;

void kbcleanup( void )
{
    tcsetattr( 0, TCSAFLUSH, &oldSettings );     /* restore old settings */
}

void kbsetup( void )
{
    tcgetattr( 0, &oldSettings );

    struct termios newSettings = oldSettings;

    newSettings.c_lflag &= ~ICANON;   /* disable line-at-a-time input */
    newSettings.c_lflag &= ~ECHO;     /* disable echo */
    newSettings.c_cc[VMIN]  = 0;      /* don't wait for characters */
    newSettings.c_cc[VTIME] = 0;      /* no minimum wait time */

    if ( tcsetattr( 0, TCSAFLUSH, &newSettings ) == 0 ){
        atexit( kbcleanup );    /* restore the terminal settings when the program exits */
    } else {
        fprintf( stderr, "Unable to set terminal mode\n" );
        exit( 1 );
    }
}

int getkey( void )
{
    char c;

    if ( read( STDIN_FILENO, &c, 1 ) == 0 )
        return '\0';
    else
        return c;
}

int main( void )
{
    int c;

    kbsetup();

    time_t start = time( NULL );
    time_t previous = start;
    for (;;)
    {
        usleep( 1000 );
        time_t current = time( NULL );

        if ( current != previous )
        {
            fprintf( stderr, "tick %3ld\r", current - start );
            previous = current;
        }
        else if ( (c = getkey()) != '\0' )
        {
            if ( c == 'q' || c == 'Q' )
                break;
            printf( "\ngot char: 0x%02x", c );
            if ( isprint( c ) )
                printf( " '%c'", c );
            printf( "\n" );
        }
    }
}
2
ответ дан user3386109 22 August 2018 в 23:49
поделиться
  • 1
    Большой!! Я использовал этот код, и он, похоже, работает :) В чем именно недостатки этого, я думаю, что отключение буферизации строк / по одному приведет к некоторой форме потери функциональности? – Ikki 19 April 2015 в 00:05
  • 2
    @Ikki: он имеет тенденцию быть медленнее, потому что вы в итоге получаете больше системных вызовов и т. Д. Конечно, вы можете узнать о Canonical vs non-canonical terminal input на SO. – Jonathan Leffler 19 April 2015 в 01:05
  • 3
    @ikki Я рад, что вы спросили, потому что это заставило меня задуматься о недостатках. Ссылка от Джонатана обсуждает один недостаток, который заключается в том, что функции редактирования линии отключены. Другим недостатком является то, что постоянный опрос клавиатуры ставит один из ядер процессора на 100% (как показывает монитор активности). Добавление usleep(1000) в код ( см. Мое редактирование ) исправляет это. Задержка в миллисекундах не заметна для пользователя, но при этом использование процессора сокращается до 1,5%. Если в вашей игре уже есть встроенные задержки, спам может не понадобиться. – user3386109 19 April 2015 в 05:18
  • 4
    Спасибо кучам парней :) – Ikki 20 April 2015 в 03:49

Вы можете проверить ответы, упомянутые в другой статье stackoverflow:

Проблема с kbhit () [и getch ()] для Linux

0
ответ дан Community 22 August 2018 в 23:49
поделиться

Похоже, вы хотите дождаться нажатия клавиши, а затем продолжить выполнение:

//test.c

#include <pthread.h>
#include <stdio.h>

void *input_listener(void *threadarg)
{
  getchar();
  printf("A key was pressed.\n");
}

int main()
{
  printf("Start\n");
  pthread_t thread;
  pthread_create(&thread, NULL, input_listener, NULL);
  pthread_join(thread, NULL);

  // Continue main
}

Должно быть очень простым в использовании pthreads (необходимо скомпилировать: gcc test.c -lpthread).

2
ответ дан Vinay Dandekar 22 August 2018 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: