Захватывать символы со стандартного ввода, не дожидаясь нажатия клавиши ввода - PullRequest
150 голосов
/ 07 января 2009

Я никогда не могу вспомнить, как я это делаю, потому что это случается так редко для меня. Но в C или C ++, как лучше всего читать символ из стандартного ввода, не дожидаясь перевода строки (нажмите ввод).

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

Ответы [ 15 ]

3 голосов
/ 08 января 2009

Ниже приведено решение, извлеченное из Expert C Programming: Deep Secrets , которое должно работать на SVr4. Он использует stty и ioctl .

#include <sys/filio.h>
int kbhit()
{
 int i;
 ioctl(0, FIONREAD, &i);
 return i; /* return a count of chars available to read */
}
main()
{
 int i = 0;
 intc='';
 system("stty raw -echo");
 printf("enter 'q' to quit \n");
 for (;c!='q';i++) {
    if (kbhit()) {
        c=getchar();
       printf("\n got %c, on iteration %d",c, i);
    }
}
 system("stty cooked echo");
}
2 голосов
/ 12 июня 2015

у меня работает на windows:

#include <conio.h>
char c = _getch();
2 голосов
/ 19 февраля 2015

Я всегда хотел, чтобы цикл считывал мой ввод без нажатия клавиши возврата. это сработало для меня.

#include<stdio.h>
 main()
 {
   char ch;
    system("stty raw");//seting the terminal in raw mode
    while(1)
     {
     ch=getchar();
      if(ch=='~'){          //terminate or come out of raw mode on "~" pressed
      system("stty cooked");
     //while(1);//you may still run the code 
     exit(0); //or terminate
     }
       printf("you pressed %c\n ",ch);  //write rest code here
      }

    }
1 голос
/ 27 июня 2018

ncurses предоставляет хороший способ сделать это! Также это мой самый первый пост (который я помню), поэтому любые комментарии приветствуются. Я буду признателен за полезные, но все приветствуются!

для компиляции: g ++ -std = c ++ 11 -pthread -lncurses .cpp -o

#include <iostream>
#include <ncurses.h>
#include <future>

char get_keyboard_input();

int main(int argc, char *argv[])
{
    initscr();
    raw();
    noecho();
    keypad(stdscr,true);

    auto f = std::async(std::launch::async, get_keyboard_input);
    while (f.wait_for(std::chrono::milliseconds(20)) != std::future_status::ready)
    {
        // do some work
    }

    endwin();
    std::cout << "returned: " << f.get() << std::endl;
    return 0;
}

char get_keyboard_input()
{
    char input = '0';
    while(input != 'q')
    {
        input = getch();
    }
    return input;
}
1 голос
/ 29 августа 2012

Вы можете сделать это с помощью SDL (Простая библиотека DirectMedia), хотя я подозреваю, что вам может не понравиться его поведение. Когда я попробовал это, мне нужно было, чтобы SDL создал новое видеоокно (хотя оно мне и не понадобилось для моей программы), и чтобы это окно «захватывало» почти весь ввод с клавиатуры и мыши (что было хорошо для моего использования, но могло быть раздражающим или неработающим в других ситуациях). Я подозреваю, что это излишне и не стоит, если не требуется полная переносимость, в противном случае попробуйте одно из других предложенных решений.

Кстати, это даст вам возможность нажимать клавиши и отпускать события отдельно, если вы в этом заинтересованы.

...