Сделайте процедуру «нажми любую клавишу», которая совместима с перенаправленным стандартным вводом - PullRequest
3 голосов
/ 07 июля 2010

У меня есть программа на C / C ++, которая запускается в окне консоли и предлагает пользователю нажать любую клавишу для продолжения или «q» для выхода.В настоящее время он использует _kbhit (), чтобы определить, была ли нажата клавиша, а затем использует _getch (), чтобы определить, какой это был символ.

Теперь я хочу иметь возможность автоматизировать эту программу (из приложения на C #, используяПроцесс с установленными RedirectStandardInput и CreateNoWindow).Очевидно, я больше не могу полагаться на _kbhit (), так как он использует ReadConsoleInput (), который завершается ошибкой при запуске с использованием моего приложения на C #.В моем приложении на C # я использую process.StandardInput.Write ("A"), чтобы вставить что-то в поток, пытаясь продолжить работу моего консольного приложения.

В консольном приложении я использовал SetConsoleMode () дляочистите флаг ENABLE_LINE_INPUT, чтобы я мог использовать getchar () для возврата сразу после нажатия символа, и это работает достаточно хорошо (когда я нажимаю символьную клавишу в окне консоли, а также когда выполняется вызов из приложения c #)).Тем не менее, у него есть недостатки в том, что теперь он принимает только символьные клавиши (т. Е. Не клавиши F, Alt, Shift и т. Д.), Что не является большой проблемой, но более того, мне кажется, что мне приходится нажимать клавишу возврата дважды (и это клавишачто многие люди, скорее всего, захотят нажать в любой ситуации).

Кто-нибудь знает, как я могу заставить консольное приложение реагировать на клавишу (любой бонус, символ и возврат только приемлемы)нажал ОДИН РАЗ, в то время как все еще отвечает на единственный символ, помещенный в поток из моего приложения C #?

Что-то, что я заметил, вызывая систему («ПАУЗА»), дает точное поведение, которое я хочу, кроме знания, какая клавиша быланажал, чтобы я мог выйти на «д».Я не знаю, как это делает PAUSE, и это также не позволяет мне использовать мое собственное сообщение: (.

Я уверен, что есть действительно очевидное решение, но оно сводит меня с ума.Любые мысли очень ценятся!

Ответы [ 4 ]

2 голосов
/ 07 июля 2010

Есть две проблемы с разрешениями:

  1. Ни один из языков C или C ++ не имеет портативные функции для ожидания клавиша для удара. Это выпуск операционной системы (платформы). *
  2. C и C ++ имеют разные методы для разрешение ввода / вывода. Выбери свой язык C или C ++.

В моих консольных приложениях на C ++ я прошу пользователя «Нажать Enter, чтобы продолжить» и использовать ignore метод cin:

void Pause(void)
{
    std::cout << "Press ENTER to continue.\n";
    std::cout.flush(); // Insurance, make sure the text is displayed.
    std::cin.ignore(100000, '\n');  // Ignore characters until an ENTER (newline) is received.
    return;
}

Я предлагаю вам создать один файл с функцией Pause . Вы можете написать разные версии для разных платформ и позволить системе сборки выбрать правильный файл.

  • Не все платформы, работающие на C или C ++, должны иметь клавиатуры. Многие встроенные системы не имеют клавиатуры. Кроме того, многие оконные системы получают сообщения, события или сигналы при нажатии клавиши. Опять что-то другое и не стандартное.
1 голос
/ 07 июля 2010

Вот очень хорошая реализация для C ++.Обязательно прочитайте весь учебник, так как мне может показаться, что он вам не поможет.

http://www.daniweb.com/forums/thread90228.html

0 голосов
/ 08 июля 2010

Спасибо за все ваши ответы, я многое узнал об обработке ввода!

Однако я не мог заставить что-либо работать так, как мне хотелось, поэтому мне пришлось отказаться от единого подхода ипоставить проверку, чтобы увидеть, если он работает в окне.Если это так, я придерживаюсь _kbhit (), а если нет, я использую PeekNamedPipe (), который дает мне количество символов, отправленных из моего приложения на C # без передачи их в буфер stdin.Есть еще несколько проблем, которые я должен решить, чтобы очистить все данные, которые мне не нужны, из конвейера, но это решило мою первоначальную проблему.

Еще раз спасибо за все предложения, они, несомненно, будутпригодится в следующий раз, когда у меня будет входной кошмар:)

0 голосов
/ 07 июля 2010

Используйте cin.get (). Это возвращает соответствующий ключ.

...