Spec-Zone.ru › C

scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s

Определено в заголовочном файле <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.
signedchar* or unsignedchar*
signedshort* or unsignedshort*
signedint* or unsignedint*
signedlong* or unsignedlong*
signedlonglong* or unsignedlonglong*
intmax_t* or 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*
Н/Д Н/Д Н/Д Н/Д
longdouble*
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 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

См. также

vscanfvfscanfvsscanfvscanf_svfscanf_svsscanf_s
(C99)(C99)(C99)(C11)(C11)(C11)
считывает форматированный ввод из stdin, файлового потока или буфера
с использованием списка переменного числа аргументов
(функция)
fgets
считывает строку символов из файлового потока
(функция)
printffprintfsprintfsnprintfprintf_sfprintf_ssprintf_ssnprintf_s
(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/c/io/fscanf

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API