scanf: «% [^ \ n]» пропускает 2-й ввод, а «% [^ \ n]» - нет. почему?

Рассмотрим следующий код:

#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]" (обратите внимание на пробел перед % ), то работает нормально. Принимается ли автоматически существующий символ новой строки из предыдущего входного буфера? Но очистка стандартного ввода не решает этой проблемы.

В чем причина этого.

28
задан Nan Xiao 7 November 2016 в 02:14
поделиться

3 ответа

Когда вы используете scanf() для чтения строк, ваша строка формата (%[^\n]) говорит функции читать каждый символ, который не '\n'. Это оставляет символ '\n' во входном буфере. Поэтому, когда вы пытаетесь прочитать str2 и str3, scanf() обнаруживает, что первое, что находится в буфере - это '\n' каждый раз, и из-за строки формата не удаляет его из входного буфера. То, что вам нужно, это getchar() между временем, которое вы читаете из входного буфера (часто помещается сразу после scanf()). Поскольку в буфере уже есть '\n', ваша программа не будет зависать, потому что ей не придется ждать ввода для получения getchar(). Попытайся. :)

Для тех, кто не имеет понятия, что делает этот модификатор scanf(), вот соответствующая выдержка из http://linux.die.net/man/3/scanf -

[

Соответствует непустой последовательности символов из указанного набора принятых символов; следующий указатель должен быть указателем на символ, и должно быть достаточно места для всех символов в строке плюс завершающий нулевой байт. Обычный пропуск ведущих пробелов подавляется. Строка должна состоять из символов в (или не в) конкретном наборе; набор определяется символами между символом открытой скобки [символ и символ закрывающей скобки]. Набор исключает эти символы, если первый символ после открытой скобки является окружностью (^). Чтобы включить в набор закрывающую скобку, сделайте ее первым символом после открытой скобки или окружности; любая другая позиция завершит сет. Символ дефиса - тоже особенный; при размещении между двумя другими символами он добавляет все промежуточные символы в набор. Чтобы включить дефис, сделайте его последним символом перед последней закрывающей скобкой. Например, [^] 0-9-] означает набор «все, кроме закрывающей скобки, от нуля до девяти и дефиса». Строка заканчивается появлением символа, не входящего в (или с окружностью, в) или когда ширина поля заканчивается.

7
ответ дан 28 November 2019 в 03:13
поделиться

Просто используйте getchar () после функции scanf ().

1
ответ дан 28 November 2019 в 03:13
поделиться

используйте fflush(stdin) для очистки буфера ввода после чтения каждого ввода.

-3
ответ дан 28 November 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: