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 состоит из

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

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

Спецификатор
преобразования
Описание Тип аргумента
Модификатор длины → hh

(C++11)

h (нет) l ll

(C++11)

j

(C++11)

z

(C++11)

t

(C++11)

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(C++11)
e, E
f, F
g, G
Совпадает с числом с плавающей точкой.

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

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

Семейство функций printf должно генерировать ту же последовательность, используя спецификатор формата %p

Н/Д Н/Д
void**
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д

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

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

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

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

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

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

При разборе неполного значения с плавающей запятой, которое заканчивается экспонентой без цифр, например, при разборе "100er" со спецификатором преобразования %f, потребляется последовательность "100e" (самый длинный префикс, который может быть допустимым числом с плавающей запятой), что приводит к ошибке сопоставления (потреблённая последовательность не может быть преобразована в число с плавающей запятой), при этом остаётся "r". Некоторые существующие реализации не следуют этому правилу и отменяют потребление, потребляя только "100", оставляя "er", например, glibc bug 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/w/cpp/io/c/vfscanf

Spec-Zone.ru

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