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, указывающее размер принимающего массива, которое может быть 1 при чтении с %c в один символ char), и за исключением того, что следующие ошибки обнаруживаются во время выполнения и вызывают текущую установленную функцию обработчика ограничений обработчика ограничений:
  • любой из аргументов типа указатель является нулевым указателем
  • 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 - список переменных аргументов, содержащий принимающие аргументы.


Строка формата состоит из

  • не-пробельных многобайтовых символов, за исключением %: каждый такой символ в строке формата потребляет ровно один идентичный символ из входного потока или заставляет функцию завершиться ошибкой, если следующий символ в потоке не совпадает.
  • пробельных символов: любой одиночный пробельный символ в строке формата потребляет все доступные последовательные пробельные символы из входного потока (определяется так же, как при вызове 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 символов).

[множество] Соответствует непустой последовательности символов из множества символов.

Если первый символ множества — ^, то сопоставляются все символы, не входящие в множество. Если множество начинается с ] или ^], то символ ] также включается в множество. Определяется ли реализацией, может ли символ - в непервом положении в наборе сканирования указывать диапазон, как в [0-9] . Если используется спецификатор ширины, сопоставляются только до ширины. Всегда сохраняет нулевой символ в дополнение к сопоставленным символам (следовательно, массив аргумента должен иметь место для как минимум ширина+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*
Н/Д
i Соответствует целому числу.

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

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

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

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

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

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

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

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

Ввод не потребляется. Счёт присваиваний не увеличивается. Если у спецификатора определён оператор подавления присваивания, поведение неопределённо.

a, A(C99)
e, E
f, F(C99)
g, G
Соответствует числу с плавающей точкой.

Формат числа такой же, как ожидается от strtof

Н/Д Н/Д
float*
double*
Н/Д Н/Д Н/Д Н/Д
long double*
p Соответствует определённой реализацией последовательности символов, определяющей указатель.

Семейство функций printf должно генерировать ту же последовательность с помощью спецификатора формата %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.

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

1-3) Количество успешно присвоенных аргументов получателя или EOF в случае возникновения ошибки чтения до присвоения первого аргумента получателя.
4-6) То же, что и (1-3), за исключением того, что EOF также возвращается, если возникает нарушение временного ограничения.

Примечания

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

Пример

#include <stdio.h>
#include <stdbool.h>
#include <stdarg.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

Ссылки

  • Стандарт 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/w/c/io/vfscanf

Spec-Zone.ru

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