Что делает scanf ("% [^ \ n]% * c", & s);на самом деле делать? - PullRequest
2 голосов
/ 14 апреля 2019

Я точно знаю, что [^ \ n] - это разделитель, который заставляет scanf сканировать все, пока не будет нажата клавиша ввода.Но я не знаю, для чего используется остаток от "% [^ \ n]% * c" .Также, почему мы должны упоминать «& s» вместо «s» в функции scanf.

Я попытался запустить это:

char s[100];
scanf("%[^\n]s",s);      
scanf("%[^\n]s",&s);

Оба выше операторы scanf работали точно так же для меня .Если между ними есть какая-либо разница, что это такое?

Также Почему я предпочитаю scanf ("% [^ \ n]% * c", & s); к вышеуказанным декларациям?

Ответы [ 2 ]

5 голосов
/ 14 апреля 2019

scanf("%[^\n]s",&s); имеет много проблем:

Нет проверки возвращаемого значения.
Нет защиты от переполнения
Нет потребления '\n'
Нетприсвоение s только '\n'
Нет необходимости s в "%[^\n]s"
Неправильный тип &s с форматом.

scanf("%[^\n]s",s); имеет только одну меньшую проблему (последнюю).

Использование fgets(s, sizeof s, stdin)

if (fgets(s, sizeof s, stdin)) {
  s[strcspn(s, "\n")] = 0; // Lop off potential ending \n
  // Success
} else {
  // failure
}

  • Без проверкивозвращаемое значение

Без проверки возвращаемого значения успешность чтения неизвестна и состояние s не определено.

  • Нет защиты от переполнения

Что происходит при вводе 100-го символа?- «Очень плохо. Не хорошо. Не хорошо». Necron 99, Wizards 1977

  • Нет потребления '\n'

'\n' остается в stdin, чтобы запутать следующее чтение.

  • Нет назначения s только для '\n'

Если вход начинается с '\n', scanf () возвращает и s без изменений.Он не назначен "".

  • Нет необходимости в "s" in "%[^\n]s"

"s" не является частью спецификатора "%[^\n]".Бросьте его.

  • Неправильный тип &s с форматом.

%[...] соответствует char *, а не указателю на char[100], как &s (UB).

0 голосов
/ 14 апреля 2019

Вы можете взять строку в качестве ввода в C, используя scanf («% s», s).Но он принимает строку только до тех пор, пока не найдет первый пробел.

Чтобы взять строку в качестве ввода, вы можете использовать scanf ("% [^ \ n]% * c", s);где s определяется как char s [MAX_LEN], где MAX_LEN - максимальный размер s.Здесь [] - это символ набора сканирования.^ \ n означает принятие ввода, пока новая строка не будет найдена.Затем, с этим% * c, он читает символ новой строки, и здесь используемый * указывает, что этот символ новой строки отбрасывается.

Примечание. После ввода символа и строки введите предложение с помощью вышеупомянутогозаявление не сработает.Это потому, что в конце каждой строки присутствует символ новой строки (\ n).Итак, утверждение: scanf ("% [^ \ n]% * c", s);не будет работать, потому что последний оператор будет читать символ новой строки из предыдущей строки.Это может быть обработано различными способами, и один из них: scanf ("\ n");перед последним утверждением.

...