Как постараться не нажимать Enter с getchar ()

Если Вы используете модуль DateTime , можно звонить эпоха () метод на объекте DateTime, так как это - то, о чем Вы думаете как время Unix.

Используя DateTimes позволяет Вам преобразовывать довольно легко с эпохи, к объектам даты.

Alternativly, localtime и gmtime преобразуют эпоху в массив, содержащий дневной месяц и год, и timelocal и timegm от Время:: Локальный модуль сделает противоположное, преобразовывая массив факторов времени (секунды, минуты..., дни, месяцы и т.д.) в эпоху.

69
задан user3386109 27 September 2018 в 18:52
поделиться

7 ответов

В системе Linux вы можете изменить поведение терминала с помощью команды stty . По умолчанию терминал будет буферизовать всю информацию до тех пор, пока не будет нажата Enter , прежде чем даже отправлять ее в программу C.

Быстрый, грязный и не особо переносимый пример для изменения поведения изнутри сама программа:

#include<stdio.h>
#include<stdlib.h>

int main(void){
  int c;
  /* use system call to make terminal send all keystrokes directly to stdin */
  system ("/bin/stty raw");
  while((c=getchar())!= '.') {
    /* type a period to break out of the loop, since CTRL-D won't work raw */
    putchar(c);
  }
  /* use system call to set terminal behaviour to more normal behaviour */
  system ("/bin/stty cooked");
  return 0;
}

Обратите внимание, что это не совсем оптимально, так как это просто предполагает, что stty cooked - это то поведение, которое вы хотите при выходе из программы, а не проверка исходных настроек терминала мы. Кроме того, поскольку вся специальная обработка пропускается в необработанном режиме, многие последовательности клавиш (такие как CTRL-C или CTRL-D ) на самом деле не будут работать так, как вы ожидаете, без явного обрабатывая их в программе.

64
ответ дан 24 November 2019 в 13:41
поделиться

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

Сама библиотека C имеет дело с файлами и не заботится о том, как данные попадают во входной файл. Следовательно, в самом языке нет возможности получать клавиши по мере их нажатия; вместо этого это зависит от платформы. Поскольку вы не указали ОС или компилятор, мы не можем найти его для вас.

Кроме того, стандартный вывод обычно буферизуется для повышения эффективности. Это делается библиотеками C, поэтому существует решение C, которое заключается в fflush (stdout); после каждого записанного символа. После этого, будут ли символы отображаться немедленно, зависит от операционной системы, но все операционные системы, с которыми я знаком, будут отображать вывод немедленно, так что обычно это не проблема.

6
ответ дан 24 November 2019 в 13:41
поделиться

По умолчанию библиотека C буферизует вывод, пока не увидит возврат. Чтобы немедленно распечатать результаты, используйте fflush :

while((c=getchar())!= EOF)      
{
    putchar(c);
    fflush(stdout);
}
-1
ответ дан 24 November 2019 в 13:41
поделиться

getchar () - стандартная функция, которая на многих платформах требует, чтобы вы нажимали ENTER, чтобы получить ввод, потому что платформа буферизует ввод, пока не будет нажата эта клавиша. Многие компиляторы / платформы поддерживают нестандартный метод getch (), который не заботится о ENTER (обходит буферизацию платформы, обрабатывает ENTER как просто еще одну клавишу).

7
ответ дан 24 November 2019 в 13:41
поделиться

Поскольку вы работаете над производной Unix (Ubuntu), вот один из способов сделать это - не рекомендуется, но он будет работать (если вы можете вводить команды точно):

echo "stty -g $(stty -g)" > restore-sanity
stty cbreak
./your_program

Используйте прерывание, чтобы остановить программу, когда она вам надоест.

sh restore-sanity
  • Строка 'echo' сохраняет текущие настройки терминала как сценарий оболочки, который их восстановит.
  • Строка 'stty' отключает большую часть специальных обработка (например, Control-D не действует) и отправляет символы в программу, как только они становятся доступными. Это означает, что вы больше не можете редактировать свой ввод.
  • Строка 'sh' восстанавливает исходные настройки терминала.

Вы можете сэкономить, если 'stty sane' восстанавливает ваши настройки достаточно точно для ваших целей. Формат '-g' не переносится между версиями 'stty' (так что то, что сгенерировано в Solaris 10, не будет работать в Linux или наоборот), но концепция работает везде. Параметр 'stty sane' доступен не везде, AFAIK (но есть в Linux).

4
ответ дан 24 November 2019 в 13:41
поделиться

Это зависит от вашей ОС. Если вы работаете в UNIX-подобной среде, флаг ICANON включен по умолчанию, поэтому ввод буферизуется до следующего '\ n' или EOF . Отключив канонический режим, вы сразу получите персонажей. Это также возможно на других платформах, но прямого кроссплатформенного решения не существует.

РЕДАКТИРОВАТЬ: Я вижу, вы указали, что используете Ubuntu. Я только что опубликовал нечто подобное вчера, но имейте в виду, что это отключит многие варианты поведения вашего терминала по умолчанию.

#include<stdio.h>
#include <termios.h>            //termios, TCSANOW, ECHO, ICANON
#include <unistd.h>     //STDIN_FILENO


int main(void){   
    int c;   
    static struct termios oldt, newt;

    /*tcgetattr gets the parameters of the current terminal
    STDIN_FILENO will tell tcgetattr that it should write the settings
    of stdin to oldt*/
    tcgetattr( STDIN_FILENO, &oldt);
    /*now the settings will be copied*/
    newt = oldt;

    /*ICANON normally takes care that one line at a time will be processed
    that means it will return if it sees a "\n" or an EOF or an EOL*/
    newt.c_lflag &= ~(ICANON);          

    /*Those new settings will be set to STDIN
    TCSANOW tells tcsetattr to change attributes immediately. */
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    /*This is your part:
    I choose 'e' to end input. Notice that EOF is also turned off
    in the non-canonical mode*/
    while((c=getchar())!= 'e')      
        putchar(c);                 

    /*restore the old settings*/
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);


    return 0;
}

Вы заметите, что каждый персонаж появляется дважды. Это связано с тем, что ввод немедленно передается обратно на терминал, а затем ваша программа также возвращает его с помощью putchar () . Если вы хотите отделить вход от выхода, вам также необходимо отключить флаг ECHO. Вы можете сделать это, просто изменив соответствующую строку на:

newt.c_lflag &= ~(ICANON | ECHO); 
82
ответ дан 24 November 2019 в 13:41
поделиться

Вы можете включить библиотеку ncurses и использовать getch () вместо getchar () .

2
ответ дан 24 November 2019 в 13:41
поделиться
Другие вопросы по тегам:

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