Вопрос по c, linux – Ждать ввода пользователя в C?

3

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

Вот мой код:

#include <stdio.h>
int main() {
  char key[1];
  puts("Press any key to continue...");
  fgets(key,1,stdin);
}

Это даже не делает паузу для пользовательского ввода.

Я раньше пытался использовать getch () (ncurses). Что случилось, экран погас, и когда я нажал клавишу, он вернулся к тому, что было первоначально на экране, и я увидел:

$ ./pause
Press any key to continue...
$

Это то, что я хотел. Но все, что я хочу, это эквивалентpause команда в DOS / Windows (я использую Linux).

В Баш, вы можете использоватьread встроенный. Kerrek SB
getchar (). kennytm
Я пробовал getchar (). Мне нужно нажать Enter. Я не хочу этого делать. biggles5107
Linux имеет мультиплексные системные вызовы, такие какопро илиВыбрат ждать от некоторого дескриптора входного файла. Будьте осторожны, чтобы входы tty часто буферизовались ядром. Basile Starynkevitch

Ваш Ответ

2   ответа
10

Function: char * fgets (char * s, int count, FILE * stream)

Функция fgets считывает символы из потокового потока вплоть до символа новой строки и сохраняет их в строке s, добавляя нулевой символ для обозначения конца строки. Вы должны указать количество символов в пробелах в s, но количество прочитанных символов самое большее - 1. Дополнительное пространство символов используется для хранения нулевого символа в конце строки.

Так,fgets(key,1,stdin); читает 0 символов и возвращает. (читай: немедленно)

Используйтеgetchar илиgetline вместо.

Редактировать: fgets также не возвращается один разcountимволы @ доступны в потоке, он продолжает ждать новой строки и затем читаетcount символов, поэтому «любая клавиша» может быть неправильной формулировкой в этом случае.

Ты можешь использовать этоприме чтобы избежать буферизации строк:

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch ( void ) 
{
  int ch;
  struct termios oldt, newt;

  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );

  return ch;
}

int main()
{
    printf("Press any key to continue.\n");
    mygetch();
    printf("Bye.\n");
}
Насколько я знаю, ты не можешь, stdin буферизируется. ccKep
Почему это не дожидается моего вклада, теперь имеет смысл. Но я хочу что-то, что ждет нажатия одной клавиши, где ncurses пригодится. biggles5107
Так что, думаю, мне лучше использоватьread тогда biggles5107
Взгляни наСсылк, код внизу работал нормально для меня. (Отредактированный оригинальный ответ с полным кодом) ccKep
@ ccKep твой код тоже работает у меня (на OS X) William Morris
2

как добавить комментарий к сообщению, так что на самом деле это не ответ, а комментарий,

In linux Stdin буферизуется, поэтому вам нужно очистить его, что и происходит при нажатии «enter» на вашем терминале. Кажется, вы хотите читать из небуферизованного потока, т.е. вы хотите немедленно реагировать на нажатие клавиши (без необходимости явно сбрасывать ее).

Вы можете создать свой собственный небуферизованный поток с помощью файлового дескриптора, а затем прочитать его с помощью «getc». Возможно, вам придется использовать termios для настройки небуферизованного ввода, как предлагали другие.

Под ответом / вопросом должно быть поле, в котором вы можете напечатать свой комментарий. biggles5107
Хотя я могу делать это только на свои вопросы. biggles5107
Вам нужно определенное количество репутации, чтобы иметь возможность комментировать (возможно, 50 - не помню) Steve Walsh

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