Можно ли использовать функцию scanf()
внутри цикла, чтобы приостановить и подождать, пока пользователь нажмет ввод, чтобы продолжить?
Предположим, что стандартный вход подключен к терминалув типичной конфигурации вызов любой функции ввода, считывающей со стандартного ввода, будет блокироваться до тех пор, пока не будет нажата клавиша ввода, при условии, что буфер ввода пуст .Однако, если оно не пустое, то это зависит от того, что уже находится в буфере, и от деталей используемой функции.
В зависимости от того, что именно вы хотите, scanf()
может быть неплохой альтернативой, ноЕсть некоторые ошибки, связанные с этим.В целом, scanf()
сложно использовать правильно.
То, что мне нужно, это как в RPG, где вам нужно нажать A, чтобы увидеть остальную часть диалога.
Если вы читаете со стандартного ввода, вам необходимо понимать, что типовые терминалы строки буфера данных поступают в программу.Это означает, что они будут хранить набранные символы до тех пор, пока не будет нажата [enter]
или пока не заполнится его буфер, и только в этот момент данные будут отправлены в программу.В результате сложно ожидать нажатия любой клавиши , но [enter]
.
С другой стороны, вы должны знать о возможности нажатия других клавиш до * 1024.*.Есть несколько вещей, которые вы можете выбрать в этой ситуации, но если вам больше нечего делать, то вам, вероятно, следует просто слить все данные из ввода, пока не достигнете новой строки.
Из того, что я тестировал, эта функция кажется плохим выбором для приостановки.
Вы не описали, какой тип тестирования вы выполняли, но scanf()
сложно использовать правильно.Тем не менее, я думаю, что это хороший выбор для того, что вы пытаетесь сделать.Однако следует обратить внимание на то, что новая строка в строке формата не означает «соответствовать одной новой строке».Скорее, любой запуск одного или нескольких пробельных символов в строке формата означает «соответствовать нулю или нескольким пробельным символам», и функция не может знать, что он достиг конца пробельного запуска, пока не увидит next ,непробельный символ (или конец файла).
Вот как я бы использовал scanf
для ожидания нажатия клавиши [enter]
, с исключением чего-либо до этого:
char c;
int n;
c = 0;
switch(scanf("%*[^\n]%c", &c)) {
case 1: // a newline was scanned, corresponding to an [enter] keypress
assert(c == '\n');
break;
case 0: // the next character was a newline, or an error or EOF occurred
n = getchar(); // consume the newline
if (n == '\n') break; // else it was actually error or EOF
assert(n == EOF);
// fall through
case EOF: // end-of-file was reached or an I/O error occurred
break;
default: // should not happen
break;
}
Формат scanf
определяет именно то, что я описал.Дескриптор поля %*[^\n]
говорит, что соответствует последовательности одной или нескольких не-новых строк, но нигде не назначает их.Это пожирает любые символы, предшествующие следующей новой строке.Если это успешно, то %c
читает следующий символ, который должен быть символом новой строки.
Возвращаемое значение scanf()
сообщает вам, что на самом деле произошло, в частности, сколько полей ввода было найдено и присваивается , или специальное значение EOF
в случае, если конец файла или ошибка ввода-вывода происходят до того, как что-либо будет найдено.В частности, если первый символ, доступный для scanf
, является новой строкой, то ничто не может быть сопоставлено с первым полем, поэтому ничего не будет использовано из потока и будет возвращено 0.В этом случае вы должны попытаться использовать новую строку из потока через другой механизм, и getchar()
превосходно служит в этой роли.Возвращаемое значение 1 говорит о том, что хотя бы один не-символ новой строки был найден (но не назначен), а затем был найден и сопоставлен символ, который не мог быть чем-то иным, кроме символа новой строки.
Поскольку существует толькоодно поле в формате, для которого присвоение не подавляется, единственные возвращаемые значения: 0
, 1
и EOF
.
Но, посмотрев немного, я бывероятно, замените его следующим:
int c;
do {
c = getchar();
while (c != '\n' && c != EOF);
// ... optionally handle the c == EOF case here ...