Namespaces
Variants

scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s

Из ru.cppreference.net
< c | io
 
 
Файловый ввод/вывод
Типы и объекты
        
Функции
Доступ к файлам
(C95)
Неформатированный ввод/вывод
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

Форматированный ввод
Прямой ввод/вывод
Форматированный вывод
Позиционирование в файле
Обработка ошибок
Операции с файлами
 
Определено в заголовке <stdio.h>
int scanf( const char* format, ... );
(1) (до C99)
int scanf( const char* restrict format, ... );
(начиная с C99)
int fscanf( FILE* stream, const char* format, ... );
(2) (до C99)
int fscanf( FILE* restrict stream, const char* restrict format, ... );
(начиная с C99)
int sscanf( const char* buffer, const char* format, ... );
(3) (до 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 и сохраняет результаты в указанные места.

1) считывает данные из stdin
2) считывает данные из файлового потока stream
3) считывает данные из строки символов, завершающейся нулевым символом buffer. Достижение конца строки эквивалентно достижению условия конца файла для fscanf
4-6) То же, что и (1-3), за исключением того, что спецификаторы преобразования %c, %s и %[ ожидают два аргумента (обычный указатель и значение типа rsize_t, указывающее размер принимающего массива; это значение может быть 1 при чтении с помощью %c в один char) и за исключением того, что следующие ошибки обнаруживаются во время выполнения и вызывают установленную в данный момент функцию обработки ограничений:
  • любой из аргументов типа указатель является нулевым указателем
  • 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 - указатель на строку символов, завершающуюся нулевым символом, задающую способ чтения входных данных
... - принимающие аргументы.


Строка format состоит из:

  • символов (кроме пробельных и %) в многобайтовой кодировке: каждый такой символ в строке формата потребляет ровно один идентичный символ из входного потока; если следующий символ в потоке не совпадает, функция завершается с ошибкой.
  • пробельных символов: любой одиночный пробельный символ в строке формата потребляет все доступные последовательные пробельные символы из входного потока (определяемые как если бы вызовом isspace в цикле). Обратите внимание, что между "\n", " ", "\t\t" или другими пробельными символами в строке формата нет различия.
  • спецификаций преобразования. Каждая спецификация преобразования имеет следующий формат:
  • вводный символ %.
  • (необязательно) символ подавления присваивания *. Если этот параметр присутствует, функция не присваивает результат преобразования никакому принимающему аргументу.
  • (необязательно) целое число (больше нуля), задающее максимальную ширину поля, то есть максимальное количество символов, которое функция может потребить при выполнении преобразования, указанного текущей спецификацией преобразования. Обратите внимание, что %s и %[ могут привести к переполнению буфера, если ширина не указана.
  • (необязательно) модификатор длины, задающий размер принимающего аргумента, то есть фактический целевой тип. Это влияет на точность преобразования и правила переполнения. Тип назначения по умолчанию различается для каждого типа преобразования (см. таблицу ниже).
  • спецификатор формата преобразования.

Доступны следующие спецификаторы формата:

Спецификатор
преобразования
Пояснение Ожидаемый
тип аргумента
Модификатор длины→ hh h нет l ll j z t L
Доступно только с C99→ Да Да Да Да Да
%
Соответствует литералу %.
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
c

Соответствует символу или последовательности символов.

  • Если указан спецификатор ширины, соответствует ровно width символам (аргумент должен быть указателем на массив достаточного размера).
  • В отличие от %s и %[, не добавляет нулевой символ в конец массива.
Н/Д Н/Д
char*
wchar_t*
Н/Д Н/Д Н/Д Н/Д Н/Д
s

Соответствует последовательности непробельных символов (строке).

  • Если указан спецификатор ширины, соответствует максимум width символов или до первого пробельного символа, в зависимости от того, что встретится раньше.
  • Всегда сохраняет нулевой символ в дополнение к совпавшим символам (поэтому массив аргументов должен иметь место как минимум для width+1 символов).
[набор ]

Соответствует непустой последовательности символов из набора символов.

  • Если первый символ набора — ^, то совпадают все символы, не входящие в набор.
  • Если набор начинается с ] или ^], то символ ] также включается в набор.
  • Определено реализацией, может ли символ - в не начальной позиции в наборе сканирования указывать диапазон, как в [0-9].
  • Если указан спецификатор ширины, соответствует только максимум width символов.
  • Всегда сохраняет нулевой символ в дополнение к совпавшим символам (поэтому массив аргументов должен иметь место как минимум для width+1 символов).
d

Соответствует десятичному целому числу.

  • Формат числа такой же, как ожидается функциями strtol со значением 10 для аргумента base.
signed char* или unsigned char*
signed short* или unsigned short*
signed int* или unsigned int*
signed long* или unsigned long*
signed long long* или unsigned long long*
intmax_t* или uintmax_t*
size_t*
ptrdiff_t*
Н/Д
b (C23)

Соответствует беззнаковому двоичному целому числу.

  • Формат числа такой же, как ожидается функциями strtoul со значением 2 для аргумента base.
i

Соответствует целому числу.

  • Формат числа такой же, как ожидается функциями strtol со значением 0 для аргумента base (основание определяется по первым разобранным символам).
u

Соответствует беззнаковому десятичному целому числу.

  • Формат числа такой же, как ожидается функциями strtoul со значением 10 для аргумента base.
o

Соответствует беззнаковому восьмеричному целому числу.

  • Формат числа такой же, как ожидается функциями strtoul со значением 8 для аргумента base.
x
X

Соответствует беззнаковому шестнадцатеричному целому числу.

  • Формат числа такой же, как ожидается функциями strtoul со значением 16 для аргумента base.
n

Возвращает количество прочитанных к настоящему моменту символов.

  • Ввод не потребляется. Не увеличивает счетчик присваиваний.
  • Если для спецификатора определен оператор подавления присваивания, поведение не определено.
a (C99)
A (C99)
e
E
f
F (C99)
g
G

Соответствует числу с плавающей запятой.

  • Формат числа такой же, как ожидается функциями strtof.
Н/Д Н/Д
float*
double*
Н/Д Н/Д Н/Д Н/Д
long double*
p

Соответствует определяемой реализацией последовательности символов, задающей указатель.

  • printfФункции семейства %p должны генерировать такую же последовательность с использованием спецификатора формата
. Н/Д
void**
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
Примечания

Для каждого спецификатора преобразования, кроме n, из потока потребляется самая длинная последовательность входных символов, которая не превышает указанную ширину поля и которая либо точно соответствует ожидаемому спецификатору преобразования, либо является префиксом ожидаемой последовательности. Первый символ после этой потребленной последовательности, если таковой имеется, остается непрочитанным. Если потребленная последовательность имеет нулевую длину или не может быть преобразована, как указано выше, происходит ошибка соответствия, если только конец файла, ошибка кодирования или ошибка чтения не помешали вводу из потока; в этом случае это ошибка ввода.

За исключением спецификатора %, элемент ввода (или для %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 bug 1765.

Если спецификация преобразования недопустима, поведение не определено.

Если спецификация преобразования недопустима, поведение не определено.

Возвращаемое значение

1-3) Количество успешно присвоенных принимающих аргументов (может быть равно нулю в случае ошибки соответствия до присваивания первого принимающего аргумента) или EOF в случае ошибки ввода до присваивания первого принимающего аргумента.
4-6) То же, что и (1-3), за исключением того, что 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 <locale.h>
#include <stddef.h>
#include <stdio.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

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
  • 7.21.6.2 Функция fscanf (стр.: TBD)
  • 7.21.6.4 Функция scanf (стр.: TBD)
  • 7.21.6.7 Функция sscanf (стр.: TBD)
  • K.3.5.3.2 Функция fscanf_s (стр.: TBD)
  • K.3.5.3.4 Функция scanf_s (стр.: TBD)
  • K.3.5.3.7 Функция sscanf_s (стр.: TBD)
  • Стандарт 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

См. также

читает форматированный ввод из stdin, файлового потока или буфера
с использованием списка аргументов переменной длины
(функция)
получает строку символов из файлового потока
(функция)
выводит форматированный вывод в stdout, файловый поток или буфер
(функция)
Документация C++ для scanf, fscanf, sscanf