std::scanf, std::fscanf, std::sscanf
Определено в заголовочном файле <cstdio> | ||
|---|---|---|
int scanf( const char* format, ... ); | (1) | |
int fscanf( std::FILE* stream, const char* format, ... ); | (2) | |
int sscanf( const char* buffer, const char* format, ... ); | (3) |
Считывает данные из различных источников, интерпретирует их в соответствии с format и сохраняет результаты в указанных местах.
stdin.stream.buffer.Параметры
| stream | - | входной файловый поток для чтения |
| buffer | - | указатель на строку символов с завершающим нулевым символом, из которой выполняется чтение |
| format | - | указатель на строку символов с завершающим нулевым символом, задающую способ чтения входных данных |
| ... | - | принимающие аргументы |
Строка format состоит из
- непробельных многобайтовых символов, кроме
%: каждый такой символ в строке формата считывает из входного потока ровно один идентичный символ или приводит к ошибке функции, если следующий символ в потоке не равен ему. - пробельных символов: любой одиночный пробельный символ в строке формата считывает из входных данных все доступные идущие подряд пробельные символы (определяется так, как если бы в цикле вызывалась
std::isspace). Обратите внимание, что между"\n"," ","\t\t"и другими пробельными символами в строке формата нет разницы. - спецификаторов преобразования. Каждый спецификатор преобразования имеет следующий формат:
- начальный символ
%. -
(необязательно) символ подавления присваивания
*. Если этот параметр указан, функция не присваивает результат преобразования ни одному принимающему аргументу. -
(необязательно) целое число (больше нуля), задающее максимальную ширину поля, то есть максимальное количество символов, которое функция может считывать при выполнении преобразования, заданного текущим спецификатором преобразования. Обратите внимание, что
%sи%[могут привести к переполнению буфера, если ширина не указана. - (необязательно) модификатор длины, задающий размер принимающего аргумента, то есть фактический тип назначения. Он влияет на точность преобразования и правила переполнения. Тип назначения по умолчанию различается для разных типов преобразования (см. таблицу ниже).
- спецификатор формата преобразования.
Доступны следующие спецификаторы формата:
| Спецификатор преобразования | Описание | Ожидаемый тип аргумента |
||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Модификатор длины→ |
hh |
h | нет |
l |
ll |
j |
z |
t |
L |
|
| Доступен только начиная с C++11→ | Да | Да | Да | Да | Да | |||||
% | Соответствует литеральному символу %. | Н/П | Н/П | Н/П | Н/П | Н/П | Н/П | Н/П | Н/П | Н/П |
c | Соответствует символу или последовательности символов.
| Н/П | Н/П |
char*
|
wchar_t*
| Н/П | Н/П | Н/П | Н/П | Н/П |
s | Соответствует последовательности непробельных символов (строке).
|
|||||||||
[set ] | Соответствует непустой последовательности символов из набора символов set.
|
|||||||||
d | Соответствует десятичному целому числу.
|
signedchar* or unsignedchar*
|
signedshort* or unsignedshort*
|
signedint* or unsignedint*
|
signedlong* or unsignedlong*
|
signedlonglong* or unsignedlonglong*
|
std::intmax_t* or std::uintmax_t*
|
std::size_t*
|
std::ptrdiff_t*
| Н/П |
b (C++26) | Соответствует беззнаковому двоичному целому числу.
|
|||||||||
i | Соответствует целому числу.
|
|||||||||
u | Соответствует беззнаковому десятичному целому числу.
|
|||||||||
o | Соответствует беззнаковому восьмеричному целому числу.
|
|||||||||
xX | Соответствует беззнаковому шестнадцатеричному целому числу.
|
|||||||||
n | Возвращает количество символов, считанных к данному моменту.
|
|||||||||
a (C++11)A (C++11)eEfF (C++11)gG | Соответствует числу с плавающей точкой.
| Н/П | Н/П |
float*
|
double*
| Н/П | Н/П | Н/П | Н/П |
longdouble*
|
p | Соответствует определяемой реализацией последовательности символов, представляющей указатель.
| Н/П | Н/П |
void**
| Н/П | Н/П | Н/П | Н/П | Н/П | Н/П |
| Примечания | ||||||||||
| Для каждого спецификатора преобразования, кроме За исключением спецификатора Все спецификаторы преобразования, кроме Спецификаторы преобразования Спецификаторы преобразования Правильные спецификации преобразования для целочисленных типов фиксированной ширины ( После выполнения каждого спецификатора преобразования происходит точка следования; это позволяет сохранять несколько полей в одной и той же переменной-приёмнике. При разборе неполного значения с плавающей точкой, заканчивающегося показателем степени без цифр, например при разборе Если спецификация преобразования недопустима, поведение не определено. |
||||||||||
Возвращаемое значение
Количество успешно присвоенных принимающим аргументам значений (может быть равно нулю, если ошибка сопоставления произошла до присваивания первого принимающего аргумента) или EOF, если ошибка ввода произошла до присваивания первого принимающего аргумента.
Сложность
Не гарантируется. В частности, некоторые реализации std::sscanf имеют сложность O(N), где N = std::strlen(buffer) [1]. Для быстрого разбора строк см. std::from_chars.
Примечания
Поскольку большинство спецификаторов преобразования сначала считывают все идущие подряд пробельные символы, такой код, как
std::scanf("%d", &a);
std::scanf("%d", &b);
считает два целых числа, введённых в разных строках (второй %d считает оставшийся после первого символ новой строки) или в одной строке, разделённых пробелами или знаками табуляции (второй %d считает пробелы или знаки табуляции).
Спецификаторы преобразования, которые не считывают начальные пробельные символы, например %c, можно заставить делать это, добавив в строку формата пробельный символ:
std::scanf("%d", &a);
std::scanf(" %c", &c); // ignore the endline after %d, then read a char
Обратите внимание, что некоторые реализации 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ß水";
// parse as follows:
// %d: an integer
// %f: a floating-point value
// %9s: a string of at most 9 non-whitespace characters
// %2d: two-digit integer (digits 5 and 6)
// %f: a floating-point value (digits 7, 8, 9)
// %*d an integer which isn't stored anywhere
// ' ': all consecutive whitespace
// %3[0-9]: a string of at most 3 digits (digits 5 and 6)
// %2lc: two wide characters, using multibyte to wide conversion
const int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
&i, &x, str1, &j, &y, str2, warr);
std::cout << "Converted " << ret << " fields:\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';
}
Вывод:
Converted 7 fields: i = 25 x = 5.432 str1 = Thompson j = 56 y = 789 str2 = 56 warr[0] = U+df warr[1] = U+6c34
См. также
|
(C++11)(C++11)(C++11) | считывает форматированный ввод из stdin, файлового потока или буферас использованием списка аргументов переменной длины (функция) |
| считывает строку символов из файлового потока (функция) |
|
|
(C++11) | выводит форматированные данные в stdout, файловый поток или буфер (функция) |
|
(C++17) | преобразует последовательность символов в целое число или значение с плавающей точкой (функция) |
Документация по C для scanf, fscanf, sscanf |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/io/c/fscanf