Spec-Zone.ru › C++

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

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

См. также

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

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

Spec-Zone.ru

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