Spec-Zone.ru › C

vscanf, vfscanf, vsscanf, vscanf_s, vfscanf_s, vsscanf_s

Определено в заголовочном файле <stdio.h>
int vscanf( const char* restrict format, va_list vlist );
(1) (начиная с C99)
int vfscanf( FILE* restrict stream, const char* restrict format,
             va_list vlist );
(2) (начиная с C99)
int vsscanf( const char* restrict buffer, const char* restrict format,
             va_list vlist );
(3) (начиная с C99)
int vscanf_s(const char* restrict format, va_list vlist);
(4) (начиная с C11)
int vfscanf_s( FILE* restrict stream, const char* restrict format,
               va_list vlist);
(5) (начиная с C11)
int vsscanf_s( const char* restrict buffer, const char* restrict format,
               va_list vlist);
(6) (начиная с C11)

Считывает данные из различных источников, интерпретирует их согласно format и сохраняет результаты в местах, заданных vlist.

1) Считывает данные из stdin
2) Считывает данные из файлового потока stream
3) Считывает данные из строки символов с завершающим нулевым символом buffer. Достижение конца строки эквивалентно достижению конца файла для fscanf
4-6) То же, что и (1-3), за исключением того, что для спецификаторов преобразования %c, %s и %[ ожидаются по два аргумента (обычный указатель и значение типа rsize_t, указывающее размер принимающего массива; при считывании с помощью %c в один символ char оно может быть равно 1), а также за исключением того, что во время выполнения обнаруживаются следующие ошибки и вызывается установленная в данный момент функция обработчика ограничений:
  • любой аргумент типа указателя является нулевым указателем
  • format, stream или buffer является нулевым указателем
  • количество символов, которое было бы записано с помощью %c, %s или %[, вместе с завершающим нулевым символом, превысило бы второй аргумент (rsize_t), переданный для каждого из этих спецификаторов преобразования
  • при необходимости — любая другая обнаруживаемая ошибка, например неизвестный спецификатор преобразования
Как и для всех функций с проверкой границ, vscanf_s, vfscanf_s и vsscanf_s гарантированно доступны только в том случае, если реализация определяет __STDC_LIB_EXT1__, а пользователь задаёт __STDC_WANT_LIB_EXT1__ целочисленную константу 1 до включения <stdio.h>.

Параметры

stream - входной файловый поток для чтения
buffer - указатель на строку символов с завершающим нулевым символом, из которой выполняется чтение
format - указатель на строку символов с завершающим нулевым символом, задающую способ чтения входных данных
vlist - список аргументов переменной длины, содержащий принимающие аргументы.


Строка 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* или unsignedchar*
signedshort* или unsignedshort*
signedint* или unsignedint*
signedlong* или unsignedlong*
signedlonglong* или unsignedlonglong*
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*
Н/Д Н/Д Н/Д Н/Д
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.

Примечания

Все эти функции вызывают va_arg как минимум один раз; после возврата значение arg не определено. Эти функции не вызывают va_end — это должен сделать вызывающий код.

Пример

#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>

bool checked_sscanf(int count, const char* buf, const char* fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    int rc = vsscanf(buf, fmt, ap);
    va_end(ap);
    return rc == count;
}

int main(void)
{
    int n, m;

    printf("Parsing '1 2'...");
    if (checked_sscanf(2, "1 2", "%d %d", &n, &m))
        puts("success");
    else
        puts("failure");

    printf("Parsing '1 a'...");
    if (checked_sscanf(2, "1 a", "%d %d", &n, &m))
        puts("success");
    else
        puts("failure");
}

Вывод:

Parsing '1 2'...success
Parsing '1 a'...failure

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
    • 7.21.6.9 Функция vfscanf (стр.: TBD)
    • 7.21.6.11 Функция vscanf (стр.: TBD)
    • 7.21.6.14 Функция vsscanf (стр.: TBD)
    • K.3.5.3.9 Функция vfscanf_s (стр.: TBD)
    • K.3.5.3.11 Функция vscanf_s (стр.: TBD)
    • K.3.5.3.14 Функция vsscanf_s (стр.: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
    • 7.21.6.9 Функция vfscanf (стр.: TBD)
    • 7.21.6.11 Функция vscanf (стр.: TBD)
    • 7.21.6.14 Функция vsscanf (стр.: TBD)
    • K.3.5.3.9 Функция vfscanf_s (стр.: TBD)
    • K.3.5.3.11 Функция vscanf_s (стр.: TBD)
    • K.3.5.3.14 Функция vsscanf_s (стр.: TBD)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 7.21.6.9 Функция vfscanf (стр.: 327)
    • 7.21.6.11 Функция vscanf (стр.: 328)
    • 7.21.6.14 Функция vsscanf (стр.: 330)
    • K.3.5.3.9 Функция vfscanf_s (стр.: 597-598)
    • K.3.5.3.11 Функция vscanf_s (стр.: 599)
    • K.3.5.3.14 Функция vsscanf_s (стр.: 602)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 7.19.6.9 Функция vfscanf (стр.: 293)
    • 7.19.6.11 Функция vscanf (стр.: 294)
    • 7.19.6.14 Функция vsscanf (стр.: 295)

См. также

scanffscanfsscanfscanf_sfscanf_ssscanf_s
(C11)(C11)(C11)
считывают форматированные входные данные из stdin, файлового потока или буфера
(функция)
vprintfvfprintfvsprintfvsnprintfvprintf_svfprintf_svsprintf_svsnprintf_s
(C99)(C11)(C11)(C11)(C11)
выводят форматированные данные в stdout, файловый поток или буфер
с использованием списка аргументов переменной длины
(функция)
Документация C++ для vscanf, vfscanf, vsscanf

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/io/vfscanf

Spec-Zone.ru

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