Неблокирующее чтение с клавиатуры - C / C ++ - PullRequest
0 голосов
/ 24 февраля 2012

Я получил эту следующую функцию, работая со мной.Но что мне нужно улучшить, так это то, что он будет читать ввод с клавиатуры (на терминале) ДАЖЕ, ЧТО ЭТО НЕ НАЖИМАЕТСЯ.Мне нужно знать, когда он НЕ нажимается (в режиме ожидания), чтобы блок switch case попадал в секцию default.На этом этапе функция read() ожидает, пока пользователь не введет данные.Может ли кто-нибудь дать предложение только на основе изменения этого следующего кода?ПРИМЕЧАНИЕ: я программист на Java и до сих пор изучаю C / C ++, поэтому, может быть, мне будет немного трудно понять это.Спасибо, ребята ..

РЕДАКТИРОВАТЬ: Я нашел эту ссылку, и, кажется, что-то связано с тем, что я ищу в строке fcntl(STDIN_FILENO,F_SETFL,flags | O_NONBLOCK);.Но так как я почти ничего не знаю в C, у меня пока нет никакой идеи о том, что он говорит.http://www.codeguru.com/forum/showthread.php?t=367082

int kfd = 0;
struct termios cooked, raw;
char c;
bool dirty = false;

//get the console in raw mode
tcgetattr(kfd, &cooked);
memcpy(&raw, &cooked, sizeof(struct termios));
raw.c_lflag &=~ (ICANON | ECHO);
// Setting a new line, then end of file
raw.c_cc[VEOL] = 1;
raw.c_cc[VEOF] = 2;
tcsetattr(kfd, TCSANOW, &raw);

puts("Reading from keyboard");
puts("=====================");
puts("Use arrow keys to navigate");

while(true){
//get the next event from the keyboard
if(read(kfd, &c, 1) < 0)
{
  perror("read():");
  exit(-1);
}

linear_ = angular_ = 0;
ROS_DEBUG("value: 0x%02X\n", c);

switch(c)
{
  case KEYCODE_L:
    ROS_DEBUG("LEFT");
    angular_ = -1.0;
    dirty = true;
    break;
  case KEYCODE_R:
    ROS_DEBUG("RIGHT");
    angular_ = 1.0;
    dirty = true;
    break;
  case KEYCODE_U:
    ROS_DEBUG("UP");
    linear_ = 1.0;
    dirty = true;
    break;
  case KEYCODE_D:
    ROS_DEBUG("DOWN");
    linear_ = -1.0;
    dirty = true;
    break;
  default:
    ROS_DEBUG("RELEASE");
    linear_ = 0;
    angular_ = 0;
    dirty = true;
    break;
}

1 Ответ

1 голос
/ 29 января 2015

ОП, кажется, ответил на их вопрос:

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

Итак, я обнаружил, что нужно добавить эти 3 строки перед входом в цикл while:

flags = fcntl(0, F_GETFL, 0); /* get current file status flags */
flags |= O_NONBLOCK;          /* turn off blocking flag */
fcntl(0, F_SETFL, flags);         /* set up non-blocking read */
...