getchar не останавливается при использовании scanf

Мне сложно понять getchar() . В следующей программе getchar работает как ожидалось:

 #include  int main() { printf("Type Enter to continue..."); getchar(); return 0; } 

Однако в следующей программе getchar не создает задержку, и программа заканчивается:

 #include  int main() { char command[100]; scanf("%s", command ); printf("Type Enter to continue..."); getchar(); return 0; } 

У меня есть следующее переплетное обходное решение, которое работает, но я не понимаю, почему:

 #include  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") 

Ввод только отправляется программе после ввода новой строки, но

 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, а новая строка считается пробелом, поэтому она остается буферной. Консольный вход обычно ориентирован на линию, поэтому последующий вызов getchar () будет немедленно возвращаться, потому что «строка» остается буферной.

 scanf("%s", command ); while( getchar() != '\n' ){ /* flush to end of input line */ } 

Точно так же, если вы используете getchar () или% c для получения одного символа, вам обычно необходимо очистить строку, но в этом случае введенный символ может сам стать новой строкой, поэтому вам нужно немного другое решение:

 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 .

Ну, у меня есть что-то проще: добавьте еще один getchar() … проблема решена!

после принятия командного ввода запустите stdin.

 fflush(stdin); 

но очистка входного streamа приводит к неопределенному поведению (хотя библиотека Microsoft C определяет поведение как расширение).

Давайте будем гением компьютера.