Namespaces
Variants

vwprintf, vfwprintf, vswprintf, vwprintf_s, vfwprintf_s, vswprintf_s, vsnwprintf_s

С ru.cppreference.net
 
 
Файловый ввод/вывод
Типы и объекты
        
Функции
Доступ к файлам
(C95)
Неформатированный ввод/вывод
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

Форматированный ввод
Прямой ввод/вывод
Форматированный вывод
Позиционирование в файле
Обработка ошибок
Операции с файлами
 
Определено в заголовке <wchar.h>
int vwprintf( const wchar_t* format, va_list vlist );
(1) (начиная с C95)
(до C99)
int vwprintf( const wchar_t* restrict format, va_list vlist );
(начиная с C99)
int vfwprintf( FILE* stream, const wchar_t* format, va_list vlist );
(2) (начиная с C95)
(до C99)
int vfwprintf( FILE* restrict stream,
               const wchar_t* restrict format, va_list vlist );
(начиная с C99)
int vswprintf( wchar_t* buffer, size_t bufsz,
               const wchar_t* format, va_list vlist );
(3) (начиная с C95)
(до C99)
int vswprintf( wchar_t* restrict buffer, size_t bufsz,
               const wchar_t* restrict format, va_list vlist );
(начиная с C99)
int vwprintf_s( const wchar_t* restrict format, va_list vlist);
(4) (начиная с C11)
int vfwprintf_s( FILE* restrict stream,
                 const wchar_t* restrict format, va_list vlist);
(5) (начиная с C11)
int vswprintf_s( wchar_t* restrict buffer, rsize_t bufsz,
                 const wchar_t* restrict format, va_list vlist);
(6) (начиная с C11)
int vsnwprintf_s( wchar_t* restrict buffer, rsize_t bufsz,
                  const wchar_t* restrict format, va_list vlist);
(7) (начиная с C11)

Загружает данные из местоположений, заданных vlist, преобразует их в широкие строковые эквиваленты и записывает результаты в различные приемники.

1) Записывает результаты в stdout.
2) Записывает результаты в файловый поток stream.
3) Записывает результаты в широкую строку buffer. Записывается не более bufsz - 1 широких символов, за которыми следует нулевой широкий символ. Результирующая строка широких символов будет завершена нулевым широким символом, если только bufsz не равно нулю.
4-6) То же, что и (1-3), за исключением того, что следующие ошибки обнаруживаются во время выполнения и вызывают установленную в данный момент функцию обработчика ограничений:
  • спецификатор преобразования %n присутствует в format
  • любой из аргументов, соответствующих %s, является нулевым указателем
  • format или buffer является нулевым указателем
  • bufsz равно нулю или больше RSIZE_MAX / sizeof(wchar_t)
  • ошибки кодирования возникают в любых спецификаторах преобразования строк и символов
  • (только для vswprintf_s), строка, подлежащая сохранению в buffer (включая завершающий нулевой широкий символ), будет превышать bufsz.
7) То же, что и (6), за исключением того, что результат будет обрезан, чтобы поместиться в массив, на который указывает buffer.
Как и все функции с проверкой границ, vwprintf_s, vfwprintf_s, vswprintf_s и vsnwprintf_s гарантированно доступны только в том случае, если __STDC_LIB_EXT1__ определена реализацией и если пользователь определяет __STDC_WANT_LIB_EXT1__ как целочисленную константу 1 перед включением <stdio.h>.

Параметры

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


Строка format состоит из обычных широких символов (за исключением %), которые копируются без изменений в выходной поток, и спецификаций преобразования. Каждая спецификация преобразования имеет следующий формат:

  • вводный символ %.
  • (необязательно) один или несколько флагов, изменяющих поведение преобразования:
  • -: результат преобразования выравнивается по левому краю поля (по умолчанию — по правому).
  • +: знак знаковых преобразований всегда добавляется к результату преобразования (по умолчанию результат предваряется минусом только в случае отрицательного значения).
  • пробел: если результат знакового преобразования не начинается со знакового символа или пуст, перед результатом добавляется пробел. Игнорируется, если присутствует флаг +.
  • #: выполняется альтернативная форма преобразования. Подробные эффекты см. в таблице ниже, в противном случае поведение не определено.
  • 0: для преобразований целых чисел и чисел с плавающей запятой для заполнения поля вместо символов пробел используются начальные нули. Для целых чисел игнорируется, если явно указана точность. Для других преобразований использование этого флага приводит к неопределенному поведению. Игнорируется, если присутствует флаг -.
  • (необязательно) целое значение или *, которое задает минимальную ширину поля. Результат дополняется символами пробел (по умолчанию), если необходимо, слева при выравнивании по правому краю или справа при выравнивании по левому. В случае использования * ширина задается дополнительным аргументом типа int, который появляется перед аргументом, подлежащим преобразованию, и аргументом, предоставляющим точность, если таковая указана. Если значение аргумента отрицательно, это приводит к указанию флага - и положительной ширины поля (Примечание: Это минимальная ширина: значение никогда не усекается.).
  • (необязательно) . за которым следует целое число или *, или ничего, что задает точность преобразования. В случае использования * точность задается дополнительным аргументом типа int, который появляется перед аргументом, подлежащим преобразованию, но после аргумента, предоставляющего минимальную ширину поля, если таковой указан. Если значение этого аргумента отрицательно, оно игнорируется. Если не используется ни число, ни *, точность принимается равной нулю. Подробные эффекты точности см. в таблице ниже.
  • (необязательно) модификатор длины, который задает размер аргумента (в сочетании со спецификатором формата преобразования он определяет тип соответствующего аргумента).
  • спецификатор формата преобразования.

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

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

Записывает одиночный символ.

  • Аргумент сначала преобразуется в wchar_t как бы вызовом btowc.
  • Если используется модификатор l, аргумент wint_t сначала преобразуется в wchar_t.
Н/Д Н/Д
int
wint_t
Н/Д Н/Д Н/Д Н/Д Н/Д
s

Записывает строку символов.

  • Аргумент должен быть указателем на начальный элемент массива символов, содержащего последовательность многобайтовых символов, начинающуюся в начальном состоянии сдвига, которая преобразуется в массив широких символов, как бы вызовом mbrtowc с инициализированным нулями состоянием преобразования.
  • Точность задает максимальное количество широких символов для записи. Если Точность не указана, записываются все широкие символы вплоть до первого нулевого терминатора, не включая его.
  • Если используется спецификатор l, аргумент должен быть указателем на начальный элемент массива wchar_t.
Н/Д Н/Д
char*
wchar_t*
Н/Д Н/Д Н/Д Н/Д Н/Д
d
i

Преобразует знаковое целое в десятичное представление [-]dddd.

  • Точность задает минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не дает символов.
  • Для модификатора z ожидаемый тип аргумента — знаковая версия size_t.
signed char
short
int
long
long long
intmax_t
※
ptrdiff_t
Н/Д
b
B (необязательно)

(C23)

Преобразует беззнаковое целое в двоичное представление bbbb.

  • Точность задает минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не дает символов.
  • В альтернативной реализации 0b или 0B добавляется префикс к результатам, если преобразованное значение отлично от нуля.
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
uintmax_t
size_t
беззнаковая версия ptrdiff_t
Н/Д
o

Преобразует беззнаковое целое в восьмеричное представление oooo.

  • Точность задает минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не дает символов.
  • В альтернативной реализации точность увеличивается при необходимости, чтобы записать один ведущий ноль. В этом случае, если и преобразованное значение, и точность равны 0, записывается один 0.
Н/Д
x
X

Преобразует беззнаковое целое в шестнадцатеричное представление hhhh.

  • Для преобразования x используются буквы abcdef.
  • Для преобразования X используются буквы ABCDEF.
  • Точность задает минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не дает символов.
  • В альтернативной реализации 0x или 0X добавляется префикс к результатам, если преобразованное значение отлично от нуля.
Н/Д
u

Преобразует беззнаковое целое в десятичное представление dddd.

  • Точность задает минимальное количество отображаемых цифр.
  • Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не дает символов.
Н/Д
f
F (C99)

Преобразует число с плавающей запятой в десятичную запись в стиле [-]ddd.ddd.

  • Точность задает точное количество цифр, отображаемых после десятичной точки.
  • Точность по умолчанию — 6.
  • В альтернативной реализации десятичная точка записывается, даже если за ней не следует ни одной цифры.
  • Для стиля преобразования бесконечности и не-числа см. примечания.
Н/Д Н/Д
double
double (C99)
Н/Д Н/Д Н/Д Н/Д
long double
e
E

Преобразует число с плавающей запятой в экспоненциальную десятичную запись.

  • Для стиля преобразования e используется [-]d.ddd e±dd.
  • Для стиля преобразования E используется [-]d.ddd E±dd.
  • Экспонента содержит как минимум две цифры, при необходимости используются дополнительные цифры.
  • Если значение равно 0, экспонента также равна 0.
  • Точность задает точное количество цифр, отображаемых после десятичной точки.
  • Точность по умолчанию — 6.
  • В альтернативной реализации десятичная точка записывается, даже если за ней не следует ни одной цифры.
  • Для стиля преобразования бесконечности и не-числа см. примечания.
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
a
A

(C99)

Преобразует число с плавающей запятой в шестнадцатеричную экспоненциальную запись.

  • Для стиля преобразования a используется [-] 0xh.hhh p±d.
  • Для стиля преобразования A используется [-] 0Xh.hhh P±d.
  • Первая шестнадцатеричная цифра не равна 0, если аргумент является нормализованным значением с плавающей запятой.
  • Если значение равно 0, экспонента также равна 0.
  • Точность задает точное количество цифр, отображаемых после шестнадцатеричной точки.
  • Точность по умолчанию достаточна для точного представления значения.
  • В альтернативной реализации десятичная точка записывается, даже если за ней не следует ни одной цифры.
  • Для стиля преобразования бесконечности и не-числа см. примечания.
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
g
G

Преобразует число с плавающей запятой в десятичную или экспоненциальную десятичную запись в зависимости от значения и точности.

  • Для стиля преобразования g преобразование будет выполнено в стиле e или f.
  • Для стиля преобразования G преобразование будет выполнено в стиле E или f(до C99)F(начиная с C99).
  • Пусть P равно точности, если она отлична от нуля, 6 если точность не указана, или 1 если точность равна 0. Тогда, если преобразование в стиле E имело бы экспоненту X:
    • Если P > X ≥ −4, преобразование выполняется в стиле f или F(начиная с C99) с точностью P − 1 − X.
    • В противном случае преобразование выполняется в стиле e или E с точностью P − 1.
  • Если не запрошено альтернативное представление, конечные нули удаляются, а также удаляется десятичная точка, если не остается дробной части.
  • Для стиля преобразования бесконечности и не-числа см. примечания.
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
n

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

  • Результат записывается в значение, на которое указывает аргумент.
  • Спецификация не может содержать флаг, ширину поля или точность.
  • Для модификатора z ожидаемый тип аргумента — S*, где S — знаковая версия size_t.
signed char*
short*
int*
long*
long long*
intmax_t*
※
 ptrdiff_t* 
Н/Д
p

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

Н/Д Н/Д
void*
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
Примечания

Функции преобразования чисел с плавающей запятой преобразуют бесконечность в inf или infinity. Какая из них используется, зависит от реализации.

Не-число преобразуется в nan или nan(char_sequence). Какая из них используется, зависит от реализации.

Преобразования F, E, G, A выводят INF, INFINITY, NAN соответственно.

Спецификатор преобразования, используемый для печати char, unsigned char, signed char, short и unsigned short, ожидает продвинутые типы продвижения аргументов по умолчанию, но перед печатью его значение будет преобразовано в char, unsigned char, signed char, short и unsigned short. Безопасно передавать значения этих типов из-за продвижения, которое происходит при вызове функции с переменным числом аргументов.

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

Спецификатор преобразования, записывающий в память %n, является распространенной целью атак безопасности, когда строки формата зависят от пользовательского ввода, и не поддерживается семейством функций с проверкой границ printf_s(начиная с C11).

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

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

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

1,4) Количество записанных широких символов в случае успеха или отрицательное значение в случае ошибки.
3) Количество записанных широких символов в случае успеха или отрицательное значение в случае ошибки. Если результирующая строка усекается из-за ограничения bufsz, функция возвращает общее количество символов (не включая завершающий нулевой широкий символ), которое было бы записано, если бы ограничение не было наложено.
2,5) количество широких символов, переданных в выходной поток, или отрицательное значение, если произошла ошибка вывода, ошибка нарушения ограничений времени выполнения или ошибка кодирования.
6) количество широких символов, записанных в buffer, не считая нулевого широкого символа (который всегда записывается, если buffer не является нулевым указателем и bufsz не равно нулю и не больше RSIZE_MAX/sizeof(wchar_t)), или ноль при нарушениях ограничений времени выполнения, и отрицательное значение при ошибках кодирования.
7) количество широких символов, не включая завершающий нулевой символ (который всегда записывается, если buffer не является нулевым указателем и bufsz не равно нулю и не больше RSIZE_MAX/sizeof(wchar_t)), которое было бы записано в buffer, если бы bufsz игнорировался, или отрицательное значение, если произошло нарушение ограничений времени выполнения или ошибка кодирования.

Примечания

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

В то время как узкие строки предоставляют vsnprintf, что позволяет определить необходимый размер выходного буфера, для широких строк нет эквивалента (до C11 vsnwprintf_s), и для определения размера буфера программа может вызвать vswprintf, проверить возвращаемое значение и перераспределить больший буфер, повторяя попытку до успеха.

vsnwprintf_s, в отличие от vswprintf_s, обрежет результат, чтобы он поместился в массив, на который указывает buffer, даже несмотря на то, что усечение рассматривается как ошибка большинством функций с проверкой границ.

Пример

#include <locale.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#include <wchar.h>

void debug_wlog(const wchar_t* fmt, ...)
{
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    char time_buf[100];
    size_t rc = strftime(time_buf, sizeof time_buf, "%D %T", gmtime(&ts.tv_sec));
    snprintf(time_buf + rc, sizeof time_buf - rc, ".%06ld UTC", ts.tv_nsec / 1000);

    va_list args;
    va_start(args, fmt);
    wchar_t buf[1024];
    int rc2 = vswprintf(buf, sizeof buf / sizeof *buf, fmt, args);
    va_end(args);

    if (rc2 > 0)
       wprintf(L"%s [debug]: %ls\n", time_buf, buf);
    else
       wprintf(L"%s [debug]: (string too long)\n", time_buf);
}

int main(void)
{
    setlocale(LC_ALL, "");
    debug_wlog(L"Logging, %d, %d, %d", 1, 2, 3);
}

Возможный вывод:

02/20/15 22:12:38.476575 UTC [debug]: Logging, 1, 2, 3

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
  • 7.29.2.5 Функция vfwprintf (стр.: TBD)
  • 7.29.2.7 Функция vswprintf (стр.: TBD)
  • 7.29.2.9 Функция vwprintf (стр.: TBD)
  • K.3.9.1.6 Функция vfwprintf_s (стр.: TBD)
  • K.3.9.1.8 Функция vsnwprintf_s (стр.: TBD)
  • K.3.9.1.9 Функция vswprintf_s (стр.: TBD)
  • K.3.9.1.11 Функция vwprintf_s (стр.: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • 7.29.2.5 Функция vfwprintf (стр.: TBD)
  • 7.29.2.7 Функция vswprintf (стр.: TBD)
  • 7.29.2.9 Функция vwprintf (стр.: TBD)
  • K.3.9.1.6 Функция vfwprintf_s (стр.: TBD)
  • K.3.9.1.8 Функция vsnwprintf_s (стр.: TBD)
  • K.3.9.1.9 Функция vswprintf_s (стр.: TBD)
  • K.3.9.1.11 Функция vwprintf_s (стр.: TBD)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 7.29.2.5 Функция vfwprintf (стр.: 417-418)
  • 7.29.2.7 Функция vswprintf (стр.: 419)
  • 7.29.2.9 Функция vwprintf (стр.: 420)
  • K.3.9.1.6 Функция vfwprintf_s (стр.: 632)
  • K.3.9.1.8 Функция vsnwprintf_s (стр.: 633-634)
  • K.3.9.1.9 Функция vswprintf_s (стр.: 634-635)
  • K.3.9.1.11 Функция vwprintf_s (стр.: 636)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 7.24.2.5 Функция vfwprintf (стр.: 363)
  • 7.24.2.7 Функция vswprintf (стр.: 364)
  • 7.24.2.9 Функция vwprintf (стр.: 365)

См. также

печатает форматированный вывод в stdout, файловый поток или буфер
с использованием списка аргументов переменной длины
(функция)
печатает форматированный вывод широких символов в stdout, файловый поток или буфер
(функция)
Документация C++ по vwprintf, vfwprintf, vswprintf