> For the complete documentation index, see [llms.txt](https://man.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://man.bsdcn.org/stdio/wprintf.3.md).

# wprintf(3)

`wprintf` — 格式化宽字符输出转换

## 名称

`wprintf`, `vwprintf`

## 库

Lb libc

## 概要

`#include <stdio.h>`

`#include <wchar.h>`

`Ft int Fn fwprintf FILE * restrict stream const wchar_t * restrict format ... Ft int Fn swprintf wchar_t * restrict ws size_t n const wchar_t * restrict format ... Ft int Fn wprintf const wchar_t * restrict format ...`

`#include <stdarg.h>`

`Ft int Fn vfwprintf FILE * restrict stream const wchar_t * restrict va_list ap Ft int Fn vswprintf wchar_t * restrict ws size_t n const wchar_t *restrict format va_list ap Ft int Fn vwprintf const wchar_t * restrict format va_list ap`

## 描述

`wprintf` 函数族根据下文所述的 `format` 产生输出。`wprintf` 和 `vwprintf` 函数将输出写入 `stdout`（标准输出流）；`fwprintf` 和 `vfwprintf` 将输出写入给定的输出 `stream`；`swprintf` 和 `vswprintf` 写入宽字符串 `ws`。

这些函数在 `format` 字符串的控制下写入输出，该字符串指定后续参数（或通过 stdarg(3) 的变长参数机制访问的参数）如何转换为输出。

这些函数返回打印的字符数（不包括用于结束字符串输出的尾随 `'\0'`）。

`swprintf` 和 `vswprintf` 函数在请求写入 `n` 个或更多宽字符时将失败。

格式字符串由零个或多个指令组成：普通字符（非 `%`），原样复制到输出流；以及转换说明，每个转换说明都会取出零个或多个后续参数。每个转换说明以 `%` 字符引入。参数必须（在类型提升后）与转换说明符正确对应。`%` 之后按顺序出现以下内容：

* 一个可选字段，由一个十进制数字字符串后跟 `$` 组成，指定下一个要访问的参数。如果未提供此字段，将使用上次访问参数之后的下一个参数。参数编号从 `1` 开始。如果格式字符串中未访问的参数与已访问的参数交替出现，结果将不确定。
* 零个或多个以下标志：
  * **`#`** 值应转换为"替代形式"。对于 `c`、`d`、`i`、`n`、`p`、`s` 和 `u` 转换，此选项无效。对于 `o` 转换，会增加数字的精度以强制输出字符串的首字符为零（除非以显式精度零打印零值的情况除外）。对于 `x` 和 `X` 转换，非零结果会在前面加上字符串 `0x`（或 `X` 转换的 `0X`）。对于 `a`、`A`、`e`、`E`、`f`、`F`、`g` 和 `G` 转换，结果始终包含小数点，即使其后没有数字（通常，只有当后面跟有数字时，这些转换的结果中才会出现小数点）。对于 `g` 和 `G` 转换，不会像通常那样移除结果中的尾随零。
  * **`0`** 零填充。对于除 `n` 外的所有转换，转换后的值在左侧用零而非空格填充。如果对数值转换（`d`、`i`、`o`、`u`、`i`、`x` 和 `X`）指定了精度，则忽略 `0` 标志。
  * **`-`** 负的字段宽度标志；转换后的值在字段边界上左对齐。除 `n` 转换外，转换后的值在右侧用空格填充，而非在左侧用空格或零填充。如果同时给出了 `-` 和 `0`，则 `-` 优先。
  * **空格** 对于带符号转换（`a`、`A`、`d`、`e`、`E`、`f`、`F`、`g`、`G` 或 `i`）产生的正数，其前应保留一个空格。
  * **`+`** 带符号转换产生的数字前必须始终放置符号。如果同时使用 `+` 和空格，则 `+` 优先。
  * **`'`** 十进制转换（`d`、`u` 或 `i`）或浮点转换（`f` 或 `F`）的整数部分应使用 localeconv(3) 返回的非货币分隔符进行千位分组和分隔。
* 一个可选的十进制数字字符串，指定最小字段宽度。如果转换后的值字符数少于字段宽度，则在左侧（或右侧，如果给出了左对齐标志）用空格填充以填满字段宽度。
* 一个可选的精度，形式为句点 `.` 后跟可选的数字字符串。如果省略数字字符串，则精度取零。对于 `d`、`i`、`o`、`u`、`x` 和 `X` 转换，这指定了要出现的最小数字位数；对于 `a`、`A`、`e`、`E`、`f` 和 `F` 转换，指定了小数点后要出现的数字位数；对于 `g` 和 `G` 转换，指定了最大有效数字位数；对于 `s` 转换，指定了从字符串打印的最大字符数。
* 一个可选的长度修饰符，指定参数的大小。以下长度修饰符对 `d`、`i`、`n`、`o`、`u`、`x` 或 `X` 转换有效：

| **修饰符**        | `d`, `i`      | `o`, `u`, `x`, `X`   | `n`             |
| -------------- | ------------- | -------------------- | --------------- |
| `hh`           | `signed char` | `unsigned char`      | `signed char *` |
| `h`            | `short`       | `unsigned short`     | `short *`       |
| `l` (ell)      | `long`        | `unsigned long`      | `long *`        |
| `ll` (ell ell) | `long long`   | `unsigned long long` | `long long *`   |
| `j`            | `intmax_t`    | `uintmax_t`          | `intmax_t *`    |
| `t`            | `ptrdiff_t`   | (见注释)                | `ptrdiff_t *`   |
| `z`            | (见注释)         | `size_t`             | (见注释)           |
| `q` *(已弃用)*    | `quad_t`      | `u_quad_t`           | `quad_t *`      |

注意：`t` 修饰符应用于 `o`、`u`、`x` 或 `X` 转换时，表示参数为大小等同于 `ptrdiff_t` 的无符号类型。`z` 修饰符应用于 `d` 或 `i` 转换时，表示参数为大小等同于 `size_t` 的有符号类型。类似地，应用于 `n` 转换时，表示参数是指向大小等同于 `size_t` 的有符号类型的指针。以下长度修饰符对 `a`、`A`、`e`、`E`、`f`、`F`、`g` 或 `G` 转换有效：

| **修饰符** | `a`, `A`, `e`, `E`, `f`, `F`, `g`, `G` |
| ------- | -------------------------------------- |
| `L`     | `long double`                          |

以下长度修饰符对 `c` 或 `s` 转换有效：

| **修饰符**   | `c`      | `s`         |
| --------- | -------- | ----------- |
| `l` (ell) | `wint_t` | `wchar_t *` |

* 一个指定要应用的转换类型的字符。

字段宽度或精度，或两者，可以用星号 `*` 或星号后跟一个或多个十进制数字和 `$`（而非数字字符串）来表示。此时，由一个 `int` 参数提供字段宽度或精度。负的字段宽度被视为左对齐标志后跟正的字段宽度；负的精度被视为省略。如果单个格式指令混合使用位置参数（`nn$`）和非位置参数，结果未定义。

转换说明符及其含义如下：

* **`diouxX`** `int`（或适当变体）参数转换为有符号十进制（`d` 和 `i`）、无符号八进制（`o`）、无符号十进制（`u`）或无符号十六进制（`x` 和 `X`）表示法。`x` 转换使用字母"`abcdef`"；`X` 转换使用字母"`ABCDEF`"。精度（如果有）给出了必须出现的最小数字位数；如果转换后的值需要更少的数字，则在左侧用零填充。
* **`DOU`** `long int` 参数转换为有符号十进制、无符号八进制或无符号十进制，分别如同格式为 `ld`、`lo` 或 `lu`。这些转换字符已弃用，最终将消失。
* **`eE`** `double` 参数经舍入后按 `[-]d.ddd e±dd` 风格转换，其中小数点字符前有一位数字，小数点后的数字位数等于精度；如果未指定精度，取为 6；如果精度为零，不出现小数点字符。`E` 转换使用字母 `E`（而非 `e`）引入指数。指数始终至少包含两位数字；如果值为零，指数为 00。对于 `a`、`A`、`e`、`E`、`f`、`F`、`g` 和 `G` 转换，使用小写转换字符时，正负无穷分别表示为 `inf` 和 `-inf`，使用大写转换字符时分别表示为 `INF` 和 `-INF`。类似地，使用小写转换时 NaN 表示为 `nan`，使用大写转换时表示为 `NAN`。
* **`fF`** `double` 参数经舍入后按 `[-]ddd.ddd` 风格转换为十进制表示法，其中小数点字符后的数字位数等于精度规范。如果未指定精度，取为 6；如果精度显式为零，不出现小数点字符。如果出现小数点，则其前至少有一位数字。
* **`gG`** `double` 参数按 `f` 或 `e` 风格（或 `G` 转换的 `F` 或 `E` 风格）转换。精度指定有效数字位数。如果未指定精度，取为 6 位；如果精度为零，视为 1。当转换的指数小于 -4 或大于等于精度时，使用 `e` 风格。移除结果小数部分中的尾随零；仅当其后跟至少一位数字时才出现小数点。
* **`aA`** `double` 参数转换为 `[-]0xh.hhhp±d` 风格的十六进制表示法，其中十六进制小数点字符后的数字位数等于精度规范。如果未指定精度，取为足以精确表示该浮点数的位数；如果精度显式为零，不出现十六进制小数点字符。这是尾数+指数内部浮点表示的精确转换；`[-]0xh.hhh` 部分精确表示尾数；只有非规格化尾数在十六进制小数点左侧为零。`p` 是字面字符 `p`；指数前带正负号，以十进制表示，仅使用足以表示该指数的字符数。`A` 转换使用前缀"`0X`"（而非"`0x`"）、字母"`ABCDEF`"（而非"`abcdef`"）表示十六进制数字，以及字母 `P`（而非 `p`）分隔尾数和指数。
* **`C`** 视为带 `l` (ell) 修饰符的 `c`。
* **`c`** `int` 参数转换为 `unsigned char`，然后如同 btowc(3) 般转换为 `wchar_t`，并写入结果字符。如果使用 `l` (ell) 修饰符，`wint_t` 参数转换为 `wchar_t` 并写入。
* **`S`** 视为带 `l` (ell) 修饰符的 `s`。
* **`s`** `char *` 参数应为指向包含多字节序列的字符类型数组（指向字符串的指针）的指针。数组中的字符转换为宽字符并写入，直到（但不包括）终止 `NUL` 字符；如果指定了精度，写入的字符数不超过指定数目。如果给出了精度，无需存在 null 字符；如果未指定精度，或精度大于数组大小，数组必须包含终止 `NUL` 字符。如果使用 `l` (ell) 修饰符，`wchar_t *` 参数应为指向宽字符数组（指向宽字符串的指针）的指针。字符串中的每个宽字符都被写入。数组中的宽字符被写入，直到（但不包括）终止的宽 `NUL` 字符；如果指定了精度，写入的字符数不超过指定数目（包括移位序列）。如果给出了精度，无需存在 null 字符；如果未指定精度，或精度大于字符串中的字符数，数组必须包含终止的宽 `NUL` 字符。
* **`p`** `void *` 指针参数以十六进制打印（如同 `%#x` 或 `%#lx`）。
* **`n`** 目前已写入的字符数存储到 `int *`（或变体）指针参数所指示的整数中。不转换任何参数。
* **`%`** 写入一个 `%`。不转换任何参数。完整的转换说明为 `%%`。

小数点字符由程序的 locale（`LC_NUMERIC` 类别）定义。

字段宽度不存在或过小都不会导致数值字段截断；如果转换结果比字段宽度更宽，则扩展字段以容纳转换结果。

## 参见

btowc(3), [fputws(3)](/stdio/fputws.3.md), [printf(3)](/stdio/printf.3.md), [putwc(3)](/stdio/putwc.3.md), setlocale(3), wcsrtombs(3), [wscanf(3)](/stdio/wscanf.3.md)

## 标准

受 [printf(3)](/stdio/printf.3.md) 缺陷章节中所述注意事项的约束，`wprintf`、`fwprintf`、`swprintf`、`vwprintf`、`vfwprintf` 和 `vswprintf` 函数遵循 ISO/IEC 9899:1999 ("ISO C99")。

## 安全注意事项

参阅 [printf(3)](/stdio/printf.3.md)。
