nixp.ru v3.0

17 октября 2017,
вторник,
09:14:02 MSK

DevOps с компанией «Флант»
anonymous написал 11 января 2005 года в 15:58 (423 просмотра) Ведет себя неопределенно; открыл 1814 темы в форуме, оставил 5575 комментариев на сайте.

Tovarishi! У меня вот какая проблема. Нужно написть прогу на С под Юникс — ждеш 10 сек., если была нажата хоть какая-то клавиша — то выводиш »…….. » если нет — то выводиш «…….». Вроде элементарная. Но тут такая проблема — я не нашол ни одной функции для ввода, которая не требова нажатия клавиши (пробовал почти всё — getchar, fgets, gets, getch … i t.d)Ничего не подходит — так как все требуют нажатияб иначи цикл не идёт дальше. Под винду написал(там есть функция KBhit, в библиотеке conio.h, которой нет под Юникс). Идей 0….А написать надо срочно.

Заранее Big Tnx аnd Respect

P.S. Forum posmotrel.

// Тему переместил(а) Dmitry Shurupov из форума «Общий по UNIX и open-source».

decvar

http://www.boutell.com/lsm/lsmbyid.cgi/001097

sas

А про сигналы забыли? Вот один примитивненький набросок. Не тестирован…

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define WAIT        10
#define NOTHING     0
static char last_key  = NOTHING;
static char key       = NOTHING;
static void alarm_handler( int sig )
{
  if ( NOTHING == last_key && NOTHING == key )
    fprintf( stdout, "No activity...\n" );
  else if ( NOTHING != key && NOTHING == last_key ) {
    fprintf( stdout, "Just Return has been pressed...\n" );
  }  
  else
    fprintf( stdout, "Last key pressed code is %d; char = [%c]\n",
      last_key, (isprint( last_key )) ? last_key : '.'
    );
  exit( EXIT_SUCCESS );
}
int main( int argc, char **argv )
{
  int res = EXIT_SUCCESS;
  fd_set rdfs;    
  signal( SIGALRM, alarm_handler );
  alarm( WAIT );
  for ( ; ; ) {
    FD_ZERO( &rdfs );
    FD_SET( STDIN_FILENO, &rdfs );
    if ( -1 == select( STDIN_FILENO + 1, &rdfs, NULL, NULL, NULL ) ) {
      perror( "select failed: " );
      res = 1;
      break;
    }
    else if ( FD_ISSET( STDIN_FILENO, &rdfs ) ) {
      read( STDIN_FILENO, &key, 1 );
      if ( '\r' != key && '\n' != key ) last_key = key;
    }
    else {
      fprintf( stderr, "Something is very wrong here... We should not be here...No timeout specified...\n");
      res = 2;
      break;  
    }
  }
  return res;
}

Удачи

— sas

vnp
sas
А про сигналы забыли? Вот один примитивненький набросок. Не тестирован…

Удачи

— sas

Зачем с сигналами-то морочиться? Просто select с таймаутом:

struct timeval tmo = { 10, 0 };
    FD_SET(fileno(stdin), &rdset);
    switch(select(fileno(stdin) + 1, &fdset, 0, 0, &tmo) {
        case -1: // error
        case 0: // timeout
        default: // можно читать
    }

Кроме того, можно поиграть с termios.

sas
vnp
Зачем с сигналами-то морочиться? Просто select с таймаутом:

Если Вы посмотрите на мой набросок, то заметите, что я сознательно не использовал таймаут (последний else). Дело в том, что он изменяется в Linux, и не меняется на многих других системах. Т.е. усложняется логика по подсчету времени, если надо всегда ждать 10 секунд, независимо от того, нажимаются клавиши или нет.

Кроме того, можно поиграть с termios.

Хорошая идея :)

Juzzzt

Всем большое спасибо.