Спецификатор преобразования
scanf()
* "%["
запускает так называемый «набор сканирования». Он имеет некоторые сходства с конструкцией регулярных выражений, которая выглядит одинаково (но она все же сильно отличается). Вот что говорит стандарт:
Соответствует непустой последовательности символов из набора ожидаемых символов (набор сканирования).
...
Спецификатор преобразования включает все последующие символы в строке формата, вплоть до соответствующей правой скобки (]). Символы в скобках (список сканирования) составляют набор сканирования, если только символ после левой скобки не является окружностью (^), и в этом случае набор содержит все символы, которые не отображаются в списке сканирования между кольцом и правой скобкой. Если спецификатор преобразования начинается с [] или [^], правый символ скобки находится в списке сканирования, а следующий следующий правый символ скобки - это совпадающая правая скобка, которая завершает спецификацию; в противном случае первый следующий символ правой скобки - это тот, который завершает спецификацию. Если символ - находится в списке сканирования и не является ни первым, ни вторым, где первый символ является ^, ни последним символом, поведение определяется реализацией.
Таким образом, scanf()
преобразование "%[\n]"
будет соответствовать символу новой строки, тогда как "%[^\n]"
будет соответствовать всем символам до новой строки.
Вот что П. Дж. Плаугер говорит о наборах сканирования в «Стандартной библиотеке C»:
Набор сканирования ведет себя так же, как спецификатор преобразования s
. Он хранит до w
символов (по умолчанию - остальная часть ввода) в массиве символов, на который указывает ptr
. Он всегда хранит нулевой символ после любого ввода. не пропускает начальные пробелы. Он также позволяет указать, какие символы следует рассматривать как часть поля. Вы можете указать все совпадающие символы, как в %[0123456789abcdefABCDEF]
, что соответствует произвольной последовательности шестнадцатеричных цифр. Или вы можете указать все символы, которые не совпадают, как в %[^0123456789]
, который соответствует любым символам, кроме цифр.
Если вы хотите включить правую скобку (]
) в указанный вами набор символов, напишите ее сразу после открытия [
(или [^
), как в %[][]
, который сканирует квадратные скобки , Вы не можете включить нулевой символ в набор символов, который вы укажете. Некоторые реализации могут позволять вам указывать диапазон символов, используя знак минус (-
). Например, список шестнадцатеричных цифр можно записать как %[0-9abcdefABCDEF]
или даже, в некоторых случаях, как %[0-9a-fA-F]
. Обратите внимание, однако, что такое использование не является универсальным. Избегайте этого в программе, которую вы хотите сохранить максимально переносимой.