Namespaces
Variants

std:: vscanf, std:: vfscanf, std:: vsscanf

From ru.cppreference.net
< cpp ‎ | io ‎ | c
Определено в заголовочном файле <cstdio>
int vscanf ( const char * format, std :: va_list vlist ) ;
(1) (начиная с C++11)
int vfscanf ( std:: FILE * stream, const char * format, std :: va_list vlist ) ;
(2) (начиная с C++11)
int vsscanf ( const char * buffer, const char * format, std :: va_list vlist ) ;
(3) (начиная с C++11)

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

1) Считывает данные из stdin .
2) Считывает данные из файлового потока stream .
3) Считывает данные из строки символов с нулевым завершением buffer .

Содержание

Параметры

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


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

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

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

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

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

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

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

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

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

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

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

  • Формат числа такой же, как ожидается функцией std::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*
std::intmax_t* или std::uintmax_t*
std::size_t*
std::ptrdiff_t*
Н/П
b (C++26)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

За исключением спецификатора %, элемент ввода (или, для %n, количество входных символов) сначала преобразуется в тип, соответствующий спецификатору преобразования. Если присваивание не было подавлено с помощью *, результат преобразования записывается в объект, на который указывает следующий аргумент, который ещё не был записан. Если этот объект не имеет подходящего типа или если результат преобразования не может быть представлен в объекте, поведение не определено.

Все спецификаторы преобразования, кроме [, c и n, потребляют и отбрасывают все ведущие пробельные символы (определяется как при вызове std::isspace) перед попыткой разбора входных данных. Эти потреблённые символы не засчитываются в указанную максимальную ширину поля.

Спецификаторы преобразования lc, ls и l[ выполняют преобразование многобайтового в широкий символ, как если бы они вызывали std::mbrtowc с объектом std::mbstate_t, инициализированным нулём перед преобразованием первого символа.

Спецификаторы преобразования s и [ всегда сохраняют нулевой терминирующий символ в дополнение к сопоставленным символам. Размер массива назначения должен быть как минимум на единицу больше указанной ширины поля. Использование %s или %[ без указания размера массива назначения так же небезопасно, как std::gets.

Правильные спецификации преобразования для целочисленных типов фиксированной ширины (std::int8_t и т.д.) определены в заголовке <cinttypes> (хотя SCNdMAX, SCNuMAX и т.д. являются синонимами %jd, %ju и т.д.).

Существует точка следования после действия каждого спецификатора преобразования; это позволяет сохранять несколько полей в одну и ту же переменную-«приёмник».

При разборе неполного числа с плавающей запятой, которое заканчивается на экспоненте без цифр, например, при разборе "100er" со спецификатором преобразования %f, последовательность "100e" (самый длинный префикс возможно допустимого числа с плавающей запятой) потребляется, что приводит к ошибке соответствия (потреблённая последовательность не может быть преобразована в число с плавающей запятой), при этом "r" остаётся. Некоторые существующие реализации не следуют этому правилу и откатываются, потребляя только "100", оставляя "er", например, ошибка glibc 1765.

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

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

Количество аргументов, успешно прочитанных, или EOF в случае возникновения ошибки.

Примечания

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

Пример

#include <cstdarg>
#include <cstdio>
#include <iostream>
#include <stdexcept>
void checked_sscanf(int count, const char* buf, const char *fmt, ...)
{
    std::va_list ap;
    va_start(ap, fmt);
    if (std::vsscanf(buf, fmt, ap) != count)
        throw std::runtime_error("parsing error");
    va_end(ap);
}
int main()
{
    try
    {
        int n, m;
        std::cout << "Parsing '1 2'... ";
        checked_sscanf(2, "1 2", "%d %d", &n, &m);
        std::cout << "success\n";
        std::cout << "Parsing '1 a'... ";
        checked_sscanf(2, "1 a", "%d %d", &n, &m);
        std::cout << "success\n";
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << '\n';
    }
}

Вывод:

Parsing '1 2'... success
Parsing '1 a'... parsing error

Смотрите также

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