указатель на строку символов, завершающуюся нулём, для чтения
формат
-
указатель на строку символов, завершающуюся нулём, указывающую, как читать ввод
...
-
принимаемые аргументы
Строка формата состоит из
непробельных мультибайтовых символов, кроме %: каждый такой символ в строке формата потребляет ровно один идентичный символ из входного потока, или приводит к ошибке, если следующий символ в потоке не равен ему.
пробельных символов: любой одиночный пробельный символ в строке формата потребляет все доступные последовательные пробельные символы из ввода (определяется как при вызове std::isspace в цикле). Обратите внимание, что нет разницы между "\n", " ", "\t\t" или другими пробельными символами в строке формата.
спецификаций преобразования. Каждая спецификация преобразования имеет следующий формат:
вводный символ %.
(необязательно) символ подавления присваивания *. Если эта опция присутствует, функция не присваивает результат преобразования ни одному принимаемому аргументу.
(необязательно) целое число (больше нуля), которое задаёт максимальную ширину поля, то есть максимальное количество символов, которое функция может потребить при выполнении преобразования, указанного текущей спецификацией преобразования. Обратите внимание, что %s и %[ могут привести к переполнению буфера, если ширина не указана.
(необязательно)модификатор длины, который задаёт размер принимаемого аргумента, то есть фактический тип назначения. Это влияет на точность преобразования и правила переполнения. Тип назначения по умолчанию различается для каждого типа преобразования (см. таблицу ниже).
спецификатор формата преобразования.
Доступны следующие спецификаторы формата:
Преобразование Спецификатор
Пояснение
Ожидаемый Тип аргумента
Модификатор длины→
hh
h
нет
l
ll
j
z
t
L
Доступно только с C++11→
Да
Да
Да
Да
Да
%
Соответствует буквальному %.
Н/П
Н/П
Н/П
Н/П
Н/П
Н/П
Н/П
Н/П
Н/П
c
Соответствует символу или последовательности символов.
Если используется спецификатор ширины, соответствует ровно width символам (аргумент должен быть указателем на массив с достаточным местом).
В отличие от %s и %[, не добавляет нулевой символ в массив.
Н/П
Н/П
char*
wchar_t*
Н/П
Н/П
Н/П
Н/П
Н/П
s
Соответствует последовательности непробельных символов (строка).
Если используется спецификатор ширины, соответствует максимум width символам или до первого пробельного символа, в зависимости от того, что наступит раньше.
Всегда сохраняет нулевой символ в дополнение к соответствующим символам (поэтому массив аргумента должен иметь место по крайней мере для width+1 символов).
[набор ]
Соответствует непустой последовательности символов из набора символов.
Если первый символ набора — ^, то соответствуют все символы, не входящие в набор.
Если набор начинается с ] или ^], то символ ] также включается в набор.
Определяется реализацией, может ли символ - в не начальной позиции в сканируемом наборе указывать диапазон, как в [0-9].
Если используется спецификатор ширины, соответствует только до width.
Всегда сохраняет нулевой символ в дополнение к соответствующим символам (поэтому массив аргумента должен иметь место по крайней мере для width+1 символов).
d
Соответствует десятичному целому числу.
Формат числа такой же, как ожидается std::strtol со значением 10 для аргумента base.
signedchar* или unsignedchar*
signedshort* или unsignedshort*
signedint* или unsignedint*
signedlong* или unsignedlong*
signedlonglong* или unsignedlonglong*
std::intmax_t* или std::uintmax_t*
std::size_t*
std::ptrdiff_t*
Н/П
b(C++26)
Соответствует беззнаковому двоичному целому числу.
Формат числа такой же, как ожидается std::strtoul со значением 2 для аргумента base.
i
Соответствует целому числу.
Формат числа такой же, как ожидается std::strtol со значением 0 для аргумента base (основание определяется по первому разобранному символу).
u
Соответствует беззнаковому десятичному целому числу.
Формат числа такой же, как ожидается std::strtoul со значением 10 для аргумента base.
o
Соответствует беззнаковому восьмеричному целому числу.
Формат числа такой же, как ожидается std::strtoul со значением 8 для аргумента base.
x X
Соответствует беззнаковому шестнадцатеричному целому числу.
Формат числа такой же, как ожидается std::strtoul со значением 16 для аргумента base.
n
Возвращает количество прочитанных на данный момент символов.
Ввод не потребляется. Не увеличивает счётчик присваиваний.
Если спецификатор имеет оператор подавления присваивания, поведение не определено.
a(C++11) A(C++11) e E f F(C++11) g G
Соответствует числу с плавающей точкой.
Формат числа такой же, как ожидается std::strtof.
Н/П
Н/П
float*
double*
Н/П
Н/П
Н/П
Н/П
longdouble*
p
Соответствует определяемой реализацией последовательности символов, задающей указатель.
printfСемейство функций %p должно создавать ту же последовательность с использованием спецификатора формата
.
Н/П
void**
Н/П
Н/П
Н/П
Н/П
Н/П
Н/П
Примечания
Для каждого спецификатора преобразования, кроме n, со входного потока потребляется самая длинная последовательность входных символов, которая не превышает заданную ширину поля и которая либо точно соответствует тому, что ожидает спецификатор преобразования, либо является префиксом последовательности, которую он бы ожидал. Первый символ, если таковой имеется, после этой потреблённой последовательности остаётся непрочитанным. Если потреблённая последовательность имеет нулевую длину или если потреблённую последовательность невозможно преобразовать, как указано выше, происходит ошибка соответствия, если только конец файла, ошибка кодирования или ошибка чтения не препятствовали вводу из потока, в этом случае это ошибка ввода.
За исключением спецификатора %, элемент ввода (или, для %n, количество входных символов) сначала преобразуется в тип, соответствующий спецификатору преобразования. Если присваивание не было подавлено с помощью *, результат преобразования записывается в объект, на который указывает следующий аргумент, который ещё не был записан. Если этот объект не имеет подходящего типа, или если результат преобразования не может быть представлен в объекте, поведение не определено.
Все спецификаторы преобразования, кроме [, c и n, потребляют и отбрасывают все начальные пробельные символы (определяется как при вызове std::isspace) перед попыткой разбора ввода. Эти потреблённые символы не учитываются в заданной максимальной ширине поля.
Спецификаторы преобразования lc, ls и l[ выполняют преобразование мультибайтовых символов в широкие, как если бы при вызове std::mbrtowc с объектом std::mbstate_t, инициализированным нулём перед преобразованием первого символа.
Спецификаторы преобразования s и [ всегда сохраняют нулевой терминатор в дополнение к соответствующим символам. Размер массива назначения должен быть не менее чем на единицу больше указанной ширины поля. Использование %s или %[ без указания размера массива назначения так же опасно, как std::gets.
После действия каждого спецификатора преобразования существует точка последовательности; это позволяет сохранять несколько полей в одну и ту же переменную «приёмник».
При разборе неполного значения с плавающей точкой, которое заканчивается показателем степени без цифр, например, при разборе "100er" со спецификатором преобразования %f, последовательность "100e" (самый длинный префикс возможно допустимого числа с плавающей точкой) потребляется, что приводит к ошибке соответствия (потреблённая последовательность не может быть преобразована в число с плавающей точкой), при этом "r" остаётся. Некоторые существующие реализации не следуют этому правилу и откатываются до потребления только "100", оставляя "er", например, glibc bug 1765.
Если спецификация преобразования недопустима, поведение не определено.
Возвращаемое значение
Количество успешно присвоенных принимающих аргументов (которое может быть нулевым в случае сбоя сопоставления до присвоения первого принимающего аргумента), или
EOF
если ошибка ввода происходит до присвоения первого принимающего аргумента.
Сложность
Не гарантируется. В частности, некоторые реализации
std::sscanf
имеют сложность
O(N)
, где
N
=
std::
strlen
(
buffer
)
[1]
. Для производительного разбора строк рекомендуется использовать
std::from_chars
.
Примечания
Поскольку большинство спецификаторов преобразования сначала потребляют все последовательные пробельные символы, код вида
std::scanf("%d", &a);
std::scanf("%d", &b);
будет считывать два целых числа, введённых на разных строках (второй
%
d
поглотит оставшийся символ новой строки от первого) или на одной строке, разделённых пробелами или табуляциями (второй
%
d
поглотит пробелы или табуляции).
The conversion specifiers that do not consume leading whitespace, such as
%
c
, can be made to do so by using a whitespace character in the format string:
std::scanf("%d", &a);
std::scanf(" %c", &c);// игнорировать перевод строки после %d, затем прочитать символ
Обратите внимание, что некоторые реализации
std::sscanf
включают вызов
std::strlen
, что делает их время выполнения линейным относительно длины всей строки. Это означает, что если
std::sscanf
вызывается в цикле для многократного разбора значений из начала строки, ваш код может работать за квадратичное время (
пример
).
Пример
Запустить этот код
#include <clocale>#include <cstdio>#include <iostream>int main(){int i, j;float x, y;char str1[10], str2[4];wchar_t warr[2];std::setlocale(LC_ALL, "en_US.utf8");char input[]="25 54.32E-1 Thompson 56789 0123 56ß水";// парсинг выполняется следующим образом:// %d: целое число// %f: число с плавающей точкой// %9s: строка длиной не более 9 символов (без пробелов)// %2d: двузначное целое число (цифры 5 и 6)// %f: число с плавающей точкой (цифры 7, 8, 9)// %*d: целое число, которое нигде не сохраняется// ' ': все последовательные пробельные символы// %3[0-9]: строка длиной не более 3 цифр (цифры 5 и 6)// %2lc: два широких символа с преобразованием multibyte в wideconstint ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
&i, &x, str1, &j, &y, str2, warr);std::cout<<"Преобразовано "<< ret <<" полей:\n""i = "<< i <<"\n""x = "<< x <<"\n""str1 = "<< str1 <<"\n""j = "<< j <<"\n""y = "<< y <<"\n""str2 = "<< str2 <<std::hex<<"\n""warr[0] = U+"<<(int)warr[0]<<"\n""warr[1] = U+"<<(int)warr[1]<<'\n';}
Вывод:
Преобразовано 7 полей:
i = 25
x = 5.432
str1 = Thompson
j = 56
y = 789
str2 = 56
warr[0] = U+df
warr[1] = U+6c34