Namespaces
Variants

scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s

From cppreference.net
< c ‎ | io
Определено в заголовочном файле <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 и сохраняет результаты в заданные места.

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→ Да Да Да Да Да
%
Соответствует литералу % .
N/A N/A N/A N/A N/A N/A N/A N/A N/A
c

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

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

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

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

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

  • Если первый символ набора - ^ , то сопоставляются все символы, не входящие в набор.
  • Если набор начинается с ] или ^] , то символ ] также включается в набор.
  • Зависит от реализации, может ли символ - в не-начальной позиции в сканирующем наборе указывать на диапазон, как в [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 *
N/A
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 .
N/A N/A
float *
double *
N/A N/A N/A N/A
long double *
p

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

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

Для каждого спецификатора преобразования, кроме 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 поглотит пробелы или табуляции).

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:
scanf("%d", &a);
scanf(" %c", &c); // пропустить все последовательные пробельные символы после %d, затем прочитать символ

Пример

#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 , файлового потока или буфера
используя список переменных аргументов
(функция)
получает строку символов из файлового потока
(функция)
выводит форматированные данные в stdout , файловый поток или буфер
(функция)
C++ документация для scanf , fscanf , sscanf