getchar не останавливается при использовании scanf
мне трудно понять getchar()
. В следующей программе getchar
работает:
#include <stdio.h>
int main()
{
printf("Type Enter to continue...");
getchar();
return 0;
}
однако, в следующей программе,getchar
не создает задержки и программа заканчивается:
#include <stdio.h>
int main()
{
char command[100];
scanf("%s", command );
printf("Type Enter to continue...");
getchar();
return 0;
}
у меня есть следующий обходной путь, который работает, но я не понимаю, почему:
#include <stdio.h>
int main()
{
char command[100];
int i;
scanf("%s", command );
printf("Type Enter to continue...");
while ( getchar() != 'n') {
i=0;
}
getchar();
return 0;
}
Итак, мои вопросы:
1. Что такое scanf
делаешь? Почему scanf
этого ?
2. Почему моя работа вокруг работает?
3. Каков хороший способ эмулировать следующий код Python:
raw_input("Type Enter to continue")
5 ответов
ввод отправляется в программу только после ввода новой строки, но
scanf("%s", command );
оставляет новую строку во входном буфере, так как %s
(1) формат останавливается, когда первый символ пробела встречается после некоторого не-пробела,getchar()
затем немедленно возвращает эту новую строку и не нужно ждать дальнейшего ввода.
ваш метод работает, потому что он очищает строку из входного буфера перед вызовом getchar()
раз больше.
чтобы эмулировать поведение, очистите входной буфер перед печатью сообщения,
scanf("%s", command);
int c;
do {
c = getchar();
}while(c != '\n' && c != EOF);
if (c == EOF) {
// input stream ended, do something about it, exit perhaps
} else {
printf("Type Enter to continue\n");
getchar();
}
(1) обратите внимание, что с помощью %s
на scanf
очень небезопасно, вы должны ограничить ввод тем, что ваш буфер может содержать с шириной поля,scanf("%99s", command)
будет читать не более 99 (sizeof(command) - 1)
) символы command
, оставляя место для 0-Терминатора.
пробел является разделителем для спецификатора формата 5y3 %s и newline считается пробелом, поэтому он остается буферизованным. Консольный вход обычно ориентирован на линию, поэтому последующий вызов getchar () вернется немедленно, потому что "линия" остается буферизованной.
scanf("%s", command );
while( getchar() != '\n' ){ /* flush to end of input line */ }
одинаково, если вы используете getchar () или %c для получения одного символа, вам обычно нужно очистить строку, но в этом случае введенный символ может быть newline так что вам нужно немного другое решение:
scanf("%c", ch );
while( ch != '\n' && getchar() != '\n' ){ /* flush to end of input line */ }
аналогично для getchar():
ch = getchar();
while( ch != '\n' && getchar() != '\n' ){ /* flush to end of input line */ }
разумно, конечно, обернуть эти решения в автономные специализированные функции ввода, которые вы можете повторно использовать, а также использовать в качестве места для размещения общего кода проверки ввода и проверки ошибок (как в ответе Даниэля Фишера, который разумно проверяет EOF - вы обычно хотите избежать дублирования этих проверок и обработки ошибок везде).
Я бы предпочел сначала использовать fgets
и затем использовать sscanf
для разбора. Я давно занимаюсь такими вещами, и поведение было более предсказуемым, чем использование plain scanf
.
после ввода команды очистите stdin.
fflush(stdin);
но промывка входного потока приводит к неопределенному поведению (хотя библиотека Microsoft C определяет поведение как расширение).