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 и сохраняет результаты в заданные места.
Содержание |
Параметры
| stream | - | входной файловый поток для чтения |
| buffer | - | указатель на строку символов с нулевым завершителем для чтения |
| format | - | указатель на строку символов с нулевым завершителем, определяющую способ чтения ввода |
| ... | - | принимающие аргументы |
Строка format состоит из
- не-пробельные многобайтовые символы, кроме % : каждый такой символ в строке формата потребляет ровно один идентичный символ из входного потока, или вызывает сбой функции, если следующий символ в потоке не совпадает.
- пробельные символы: любой одиночный пробельный символ в строке формата потребляет все доступные последовательные пробельные символы из ввода (определяется как при многократном вызове std::isspace ). Заметьте, что нет разницы между " \n " , " " , " \t \t " , или другими пробельными символами в строке формата.
- спецификации преобразования. Каждая спецификация преобразования имеет следующий формат:
-
- вводный % символ.
-
- (необязательный) символ подавления присваивания * . Если присутствует эта опция, функция не присваивает результат преобразования какому-либо принимающему аргументу.
-
- (необязательно) целое число (больше нуля), которое указывает максимальную ширину поля , то есть максимальное количество символов, которое функция может обработать при выполнении преобразования, указанного текущей спецификацией преобразования. Обратите внимание, что % s и % [ могут привести к переполнению буфера, если ширина не указана.
-
- (необязательный) модификатор длины , который указывает размер принимающего аргумента, то есть фактический тип назначения. Это влияет на точность преобразования и правила переполнения. Тип назначения по умолчанию различается для каждого типа преобразования (см. таблицу ниже).
-
- спецификатор формата преобразования.
Доступны следующие спецификаторы формата:
|
Спецификатор
преобразования |
Объяснение |
Ожидаемый
тип аргумента |
||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Модификатор длины→ |
hh
|
h
|
отсутствует |
l
|
ll
|
j
|
z
|
t
|
L
|
|
| Доступно только с C++11→ | Да | Да | Да | Да | Да | |||||
%
|
Соответствует литералу
%
.
|
N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A |
c
|
Соответствует символу или последовательности символов .
|
N/A | N/A |
char
*
|
wchar_t
*
|
N/A | N/A | N/A | N/A | N/A |
s
|
Соответствует последовательности непробельных символов ( строка ).
|
|||||||||
[
set
]
|
Сопоставляет непустую последовательность символов из set набора символов.
|
|||||||||
d
|
Соответствует десятичному целому числу .
|
signed
char
*
или
unsigned
char
*
|
signed
short
*
или
unsigned
short
*
|
signed
int
*
или
unsigned
int
*
|
signed
long
*
или
unsigned
long
*
|
signed
long
long
*
или
unsigned
long
long
*
|
std::
intmax_t
*
или
std::
uintmax_t
*
|
Н/Д | ||
i
|
Соответствует целому числу .
|
|||||||||
u
|
Соответствует беззнаковому десятичному целому числу .
|
|||||||||
o
|
Соответствует беззнаковому восьмеричному целому числу .
|
|||||||||
x
X
|
Соответствует беззнаковому шестнадцатеричному целому числу .
|
|||||||||
n
|
Возвращает количество символов, прочитанных на данный момент .
|
|||||||||
a
(C++11)
A
(C++11)
e
E
f
F
(C++11)
g
G
|
Соответствует числу с плавающей запятой .
|
N/A | N/A |
float
*
|
double
*
|
N/A | N/A | N/A | N/A |
long
double
*
|
p
|
Соответствует определяемой реализацией последовательности символов, определяющей указатель .
|
N/A | N/A |
void
**
|
N/A | N/A | N/A | N/A | N/A | N/A |
| Примечания | ||||||||||
|
Для каждого спецификатора преобразования, кроме n , из потока считывается самая длинная последовательность входных символов, которая не превышает указанную ширину поля и которая либо точно соответствует ожиданиям спецификатора преобразования, либо является префиксом последовательности, которую он ожидает. Первый символ, если таковой имеется, после этой считанной последовательности остается непрочитанным. Если длина считанной последовательности равна нулю или если считанная последовательность не может быть преобразована, как указано выше, происходит ошибка сопоставления, если только конец файла, ошибка кодирования или ошибка чтения не предотвратили ввод из потока, в этом случае это ошибка ввода. Все спецификаторы преобразования, кроме [ , c , и n , потребляют и отбрасывают все ведущие пробельные символы (определяемые как при вызове std::isspace ) перед попыткой разбора ввода. Эти потребленные символы не учитываются в указанной максимальной ширине поля. Спецификаторы преобразования lc , ls , и l [ выполняют преобразование многобайтовых символов в широкие символы, как если бы вызывался std::mbrtowc с объектом std::mbstate_t , инициализированным нулем перед преобразованием первого символа. Спецификаторы преобразования s и [ всегда сохраняют нулевой терминатор в дополнение к сопоставленным символам. Размер целевого массива должен быть как минимум на единицу больше указанной ширины поля. Использование % s или % [ без указания размера целевого массива так же небезопасно, как std::gets . Правильные спецификации преобразования для целочисленных типов фиксированной ширины ( std::int8_t и т.д.) определены в заголовочном файле <cinttypes> (хотя SCNdMAX , SCNuMAX и т.д. являются синонимами для % jd , % ju и т.д.). Существует точка следования после действия каждого спецификатора преобразования; это позволяет сохранять несколько полей в одну и ту же переменную-приемник. При разборе неполного значения с плавающей точкой, которое заканчивается экспонентой без цифр, например, разбор "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 в wide 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 << "Преобразовано " << 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
Смотрите также
|
(C++11)
(C++11)
(C++11)
|
читает форматированный ввод из
stdin
, файлового потока или буфера
используя список переменных аргументов (функция) |
|
получает строку символов из файлового потока
(функция) |
|
|
(C++11)
|
выводит форматированные данные в
stdout
, файловый поток или буфер
(функция) |
|
(C++17)
|
преобразует последовательность символов в целочисленное или вещественное значение
(функция) |
|
Документация C
для
scanf
,
fscanf
,
sscanf
|
|