Как запустить программу во время прослушивания ввода пользователя в C?

Я пытаюсь создать игру, которая продолжает работать до тех пор, пока не будет нажата клавиша, а затем она должна взять эту клавишу и что-то с ней сделать, а затем продолжить работу в обычном режиме. Как мне это сделать?

Я нахожусь на MAC, так что, хотя я натолкнулся на библиотеку Windows с именем conio.h, которая может справиться с этим с помощью kbhit() и getch(), я не могу заставить ее работать на меня...

//
//  main.c
//  conioTesting
//
//

#include <stdio.h>
#include "myconio_mac.h"

int main(int argc, const char * argv[]) {

    int counter = 0;

    while (counter < 2) {
        if (kbhit()) {
            char key = getch();
            printf("\n Key is %c \n", key);
            printf("Keyboard hit detected \n");
        } else {
            printf("Nothing. \n");
        }
    }
    printf("Passed!!!!!!!!!! \n");
}

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" );
        }
    }
}

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

//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).

Вы можете проверить ответы, упомянутые в другом сообщении stackru:

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

Другие вопросы по тегам