scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s
Определено в заголовке <stdio.h> | ||
|---|---|---|
| (1) | ||
int scanf( const char *format, ... ); | (до C99) | |
int scanf( const char *restrict format, ... ); | (с C99) | |
| (2) | ||
int fscanf( FILE *stream, const char *format, ... ); | (до C99) | |
int fscanf( FILE *restrict stream, const char *restrict format, ... ); | (с C99) | |
| (3) | ||
int sscanf( const char *buffer, const char *format, ... ); | (до C99) | |
int sscanf( const char *restrict buffer, const char *restrict format, ... ); | (с C99) | |
int scanf_s(const char *restrict format, ...); | (4) | (с C11) |
int fscanf_s(FILE *restrict stream, const char *restrict format, ...); | (5) | (с C11) |
int sscanf_s(const char *restrict buffer, const char *restrict format, ...); | (6) | (с C11) |
Читает данные из различных источников, интерпретирует их в соответствии с format и сохраняет результаты в заданные места.
stdin
stream
buffer. Достижение конца строки эквивалентно достижению конца файла для fscanf
%c, %s, и %[ спецификаторы преобразования ожидают по два аргумента (обычный указатель и значение типа rsize_t, указывающее размер принимающего массива, которое может быть 1, когда считывание выполняется с %c в один символ) и за исключением того, что следующие ошибки обнаруживаются во время выполнения и вызывают текущую установленную функцию обработчика ограничений обработчика ограничений: -
- любой из аргументов типа указателя является нулевым указателем
-
format,stream, илиbufferявляется нулевым указателем - количество символов, которые были бы записаны
%c,%s, или%[, плюс завершающий нулевой символ, превысило бы второй (rsize_t) аргумент, предоставленный для каждого из этих спецификаторов преобразования - необязательно, любая другая обнаруживаемая ошибка, например, неизвестный спецификатор преобразования
- Как и во всех функциях с проверкой границ,
scanf_s,fscanf_s, иsscanf_sгарантированы только в том случае, если__STDC_LIB_EXT1__определено реализацией и если пользователь определяет__STDC_WANT_LIB_EXT1__целочисленной константой1перед включением<stdio.h>.
Параметры
| stream | - | поток ввода файла для чтения |
| buffer | - | указатель на нуль-терминированную строку символов для чтения |
| format | - | указатель на нуль-терминированную строку символов, определяющую способ чтения ввода |
| ... | - | принимающие аргументы. |
Строка формата состоит из
- не-пробельных многобайтовых символов кроме
%: каждый такой символ в строке формата потребляет ровно один идентичный символ из потока ввода или вызывает сбой функции, если следующий символ в потоке не совпадает. - пробельных символов: любой одиночный пробельный символ в строке формата потребляет все доступные последовательные пробельные символы из ввода (определяются так же, как если бы вызывали
isspaceв цикле). Обратите внимание, что нет разницы между"\n"," ","\t\t", или другими пробелами в строке формата. - спецификаторов преобразования. Каждый спецификатор преобразования имеет следующий формат:
- вводной
%символ. - (необязательно) символ подавления присваивания
*. Если этот параметр присутствует, функция не присваивает результат преобразования ни одному принимающему аргументу. - (необязательно) целое число (больше нуля), которое задает максимальную ширину поля, то есть максимальное количество символов, которое функция допускается потреблять при выполнении преобразования, задаваемого текущим спецификатором преобразования. Обратите внимание, что
%sи%[могут привести к переполнению буфера, если ширина не указана. - (необязательно) модификатор длины, который указывает размер принимающего аргумента, то есть фактический тип назначения. Это влияет на точность преобразования и правила переполнения. По умолчанию тип назначения отличается для каждого типа преобразования (см. таблицу ниже).
- спецификатор формата преобразования.
Доступны следующие спецификаторы формата:
| Спецификатор преобразования | Объяснение | Тип аргумента | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Модификатор длины → |
hh (C99) |
h | (нет) |
l |
ll (C99) |
j (C99) |
z (C99) |
t (C99) |
L |
|
% | Совпадает с литералом %. | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д |
c | Совпадает с символом или последовательностью символов. Если используется спецификатор ширины, совпадает ровно с шириной символов (аргумент должен быть указателем на массив с достаточным объёмом). В отличие от %s и %[, не добавляет нулевой символ в массив. | Н/Д | Н/Д |
char* |
wchar_t* | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д |
s | Совпадает с последовательностью символов без пробелов (строкой). Если используется спецификатор ширины, совпадает с максимальной шириной или до первого пробела, в зависимости от того, что произойдёт раньше. Всегда сохраняет нулевой символ дополнительно к совпавшим символам (массив аргумента должен быть размером как минимум ширина+1 символов) |
|||||||||
[множество] | Совпадает с непустой последовательностью символов из множества символов. Если первый символ множества — |
|||||||||
d | Совпадает с десятичным целым числом. Формат числа такой же, как ожидается функцией |
signed char* или unsigned char*
|
signed short* или unsigned short*
|
signed int* или unsigned int*
|
signed long* или unsigned long*
|
signed long long* или unsigned long long*
| Н/Д | |||
i | Совпадает с целым числом. Формат числа такой же, как ожидается функцией |
|||||||||
u | Совпадает с бесподписным десятичным целым числом. Формат числа такой же, как ожидается функцией |
|||||||||
o | Совпадает с бесподписным восьмеричным целым числом. Формат числа такой же, как ожидается функцией |
|||||||||
x, X | Совпадает с бесподписным шестнадцатеричным целым числом. Формат числа такой же, как ожидается функцией |
|||||||||
n | Возвращает количество прочитанных до сих пор символов. Входные данные не потребляются. Счёт присваиваний не увеличивается. Если у спецификатора определена операция подавления присваивания, поведение не определено |
|||||||||
a, A(C99)e, Ef, F(C99)g, G | Совпадает с числом с плавающей точкой. Формат числа такой же, как ожидается функцией | Н/Д | Н/Д |
float* |
double* | Н/Д | Н/Д | Н/Д | Н/Д |
long double* |
p | Совпадает с реализацией определённой последовательностью символов, определяющей указатель. Семейство функций | Н/Д | Н/Д |
void** | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д |
Для каждого спецификатора преобразования, отличного от n, самой длинной последовательностью входных символов, которая не превышает указанную ширину поля и которая либо точно соответствует тому, что ожидает спецификатор преобразования, либо является префиксом последовательности, которую он ожидал бы, является то, что потребляется из потока. Первый символ, если таковой имеется, после этой потреблённой последовательности остаётся непрочитанным. Если потреблённая последовательность имеет длину ноль или если потреблённая последовательность не может быть преобразована, как указано выше, происходит ошибка соответствия, за исключением случаев, когда произошёл конец файла, ошибка кодирования или ошибка чтения, предотвратившая ввод из потока, в этом случае это ошибка ввода.
Все спецификаторы преобразования, кроме [, c, и n, потребляют и отбрасывают все ведущие пробелы (определяемые так же, как при вызове isspace) перед попыткой парсинга входных данных. Эти потреблённые символы не учитываются в указанной максимальной ширине поля.
Спецификаторы преобразования lc, ls, и l[ выполняют преобразование многобайтовых символов в символы широкого типа так, как если бы вызывали mbrtowc с объектом mbstate_t, инициализированным нулём перед преобразованием первого символа.
Спецификаторы преобразования s и [ всегда сохраняют завершающий нулевой символ в дополнение к совпавшим символам. Размер целевого массива должен быть как минимум на единицу больше, чем указанная ширина поля. Использование %s или %[, без указания размера целевого массива, так же небезопасно, как gets.
Правильные спецификации преобразования для целых типов фиксированной ширины (int8_t, и т. д.) определены в заголовке <inttypes.h> (хотя SCNdMAX, SCNuMAX, и т. д. является синонимом %jd, %ju, и т. д.).
После действия каждого спецификатора преобразования существует точка последовательности, что позволяет хранить несколько полей в одной переменной "приёмника".
При парсинге неполного значения с плавающей точкой, которое заканчивается экспонентой без цифр, например, при парсинге "100er" со спецификатором преобразования %f, потребляется последовательность "100e" (самый длинный префикс потенциально допустимого числа с плавающей точкой), что приводит к ошибке соответствия (потреблённая последовательность не может быть преобразована в число с плавающей точкой), при этом "r" остаётся. Некоторые существующие реализации не следуют этому правилу и возвращаются, чтобы потреблять только "100", оставляя "er", например, ошибка glibc 1765.
Если спецификация преобразования недействительна, поведение не определено.
Возвращаемое значение
EOF при возникновении ошибки ввода перед назначением первого аргумента.EOF также возвращается, если возникает нарушение ограничения во время выполнения.Сложность
Не гарантируется. Заметим, что некоторые реализации sscanf имеют сложность O(N), где N = strlen(buffer) [1].
Примечания
Поскольку большинство спецификаторов преобразования сначала потребляют все последовательные пробелы, код, такой как
scanf("%d", &a);
scanf("%d", &b);будет считывать два целых числа, которые вводятся на разных строках (второе %d будет потреблять оставшуюся с новой строки, оставленную первым) или на одной строке, разделенные пробелами или табуляцией (второе %d будет потреблять пробелы или табуляцию). Спецификаторы преобразования, которые не потребляют начальные пробелы, такие как %c, могут быть настроены на потребление пробелов с помощью символа пробела в строке формата:
scanf("%d", &a);
scanf(" %c", &c); // consume all consecutive whitespace after %d, then read a charПример
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stddef.h>
#include <locale.h>
int main(void)
{
int i, j;
float x, y;
char str1[10], str2[4];
wchar_t warr[2];
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 decimal digits (digits 5 and 6)
%2lc: two wide characters, using multibyte to wide conversion */
int ret = sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
&i, &x, str1, &j, &y, str2, warr);
printf("Converted %d fields:\n"
"i = %d\n"
"x = %f\n"
"str1 = %s\n"
"j = %d\n"
"y = %f\n"
"str2 = %s\n"
"warr[0] = U+%x\n"
"warr[1] = U+%x\n",
ret, i, x, str1, j, y, str2, warr[0], warr[1]);
#ifdef __STDC_LIB_EXT1__
int n = sscanf_s(input, "%d%f%s", &i, &x, str1, (rsize_t)sizeof str1);
// writes 25 to i, 5.432 to x, the 9 bytes "Thompson\0" to str1, and 3 to n.
#endif
}Возможный вывод:
Converted 7 fields: i = 25 x = 5.432000 str1 = Thompson j = 56 y = 789.000000 str2 = 56 warr[0] = U+df warr[1] = U+6c34
Справочные материалы
- Стандарт C17 (ISO/IEC 9899:2018):
- 7.21.6.2 Функция fscanf (с. 231-236)
- 7.21.6.4 Функция scanf (с. 236-237)
- 7.21.6.7 Функция sscanf (с. 238-239)
- K.3.5.3.2 Функция fscanf_s (с. 430-431)
- K.3.5.3.4 Функция scanf_s (с. 432)
- K.3.5.3.7 Функция sscanf_s (с. 433)
- Стандарт C11 (ISO/IEC 9899:2011):
- 7.21.6.2 Функция fscanf (с. 317-324)
- 7.21.6.4 Функция scanf (с. 325)
- 7.21.6.7 Функция sscanf (с. 326)
- K.3.5.3.2 Функция fscanf_s (с. 592-593)
- K.3.5.3.4 Функция scanf_s (с. 594)
- K.3.5.3.7 Функция sscanf_s (с. 596)
- Стандарт C99 (ISO/IEC 9899:1999):
- 7.19.6.2 Функция fscanf (с. 282-289)
- 7.19.6.4 Функция scanf (с. 290)
- 7.19.6.7 Функция sscanf (с. 291)
- Стандарт C89/C90 (ISO/IEC 9899:1990):
- 4.9.6.2 Функция fscanf
- 4.9.6.4 Функция scanf
- 4.9.6.6 Функция sscanf
См. также
|
(C99)(C99)(C99)(C11)(C11)(C11) | считывает форматированный ввод из stdin, потока файла или буфера с использованием списка переменных аргументов (функция) |
| получает строку символов из потока файла (функция) |
|
|
(C99)(C11)(C11)(C11)(C11) | выводит форматированный вывод в stdout, поток файла или буфер (функция) |
Документация C++ для scanf, fscanf, sscanf |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/io/fscanf