Рассмотрим следующий код:
#include <stdio.h>
int main (void)
{
char str1[128], str2[128], str3[128];
printf ("\nEnter str1: ");
scanf ("%[^\n]", str1);
printf ("\nstr1 = %s", str1);
printf ("\nEnter str2: ");
scanf ("%[^\n]", str2);
printf ("\nstr2 = %s", str2);
printf ("\nEnter str3: ");
scanf ("%[^\n]", str3);
printf ("\nstr3 = %s", str3);
printf ("\n");
return 0;
}
Когда он выполняется, только первый scanf
останавливается для запроса. Программа не останавливается в течение следующих scanf
с. Но если строка формата изменена с "% [^ \ n]"
на "% [^ \ n]"
(обратите внимание на пробел перед %
), то работает нормально. Принимается ли автоматически существующий символ новой строки из предыдущего входного буфера? Но очистка стандартного ввода
не решает этой проблемы.
В чем причина этого.
Когда вы используете scanf()
для чтения строк, ваша строка формата (%[^\n]
) говорит функции читать каждый символ, который не '\n'
. Это оставляет символ '\n'
во входном буфере. Поэтому, когда вы пытаетесь прочитать str2
и str3
, scanf()
обнаруживает, что первое, что находится в буфере - это '\n'
каждый раз, и из-за строки формата не удаляет его из входного буфера. То, что вам нужно, это getchar()
между временем, которое вы читаете из входного буфера (часто помещается сразу после scanf()
). Поскольку в буфере уже есть '\n'
, ваша программа не будет зависать, потому что ей не придется ждать ввода для получения getchar()
. Попытайся. :)
Для тех, кто не имеет понятия, что делает этот модификатор scanf()
, вот соответствующая выдержка из http://linux.die.net/man/3/scanf -
[
Соответствует непустой последовательности символов из указанного набора принятых символов; следующий указатель должен быть указателем на символ, и должно быть достаточно места для всех символов в строке плюс завершающий нулевой байт. Обычный пропуск ведущих пробелов подавляется. Строка должна состоять из символов в (или не в) конкретном наборе; набор определяется символами между символом открытой скобки [символ и символ закрывающей скобки]. Набор исключает эти символы, если первый символ после открытой скобки является окружностью (^). Чтобы включить в набор закрывающую скобку, сделайте ее первым символом после открытой скобки или окружности; любая другая позиция завершит сет. Символ дефиса - тоже особенный; при размещении между двумя другими символами он добавляет все промежуточные символы в набор. Чтобы включить дефис, сделайте его последним символом перед последней закрывающей скобкой. Например, [^] 0-9-] означает набор «все, кроме закрывающей скобки, от нуля до девяти и дефиса». Строка заканчивается появлением символа, не входящего в (или с окружностью, в) или когда ширина поля заканчивается.
Просто используйте getchar () после функции scanf ().
используйте fflush(stdin)
для очистки буфера ввода после чтения каждого ввода.