std::printf,std::fprintf,std::sprintf,std::snprintf
C++
Compiler support
Freestanding and hosted
Language
Standard library
Standard library headers
Named requirements
Feature test macros
(C++20)
Language support library
Concepts library
(C++20)
Diagnostics library
Memory management library
Metaprogramming library
(C++11)
General utilities library
Containers library
Iterators library
Ranges library
(C++20)
Algorithms library
Strings library
Text processing library
Numerics library
Date and time library
Input/output library
Filesystem library
(C++17)
Concurrency support library
(C++11)
Execution control library
(C++26)
Technical specifications
Symbols index
External libraries
Input/output library
I/O manipulators
Print functions
(C++23)
C-style I/O
Buffers
basic_streambuf
basic_filebuf
basic_stringbuf
basic_spanbuf
(C++23)
strstreambuf
(
C++98/26*
)
basic_syncbuf
(C++20)
Streams
Abstractions
ios_base
basic_ios
basic_istream
basic_ostream
basic_iostream
File I/O
basic_ifstream
basic_ofstream
basic_fstream
String I/O
basic_istringstream
basic_ostringstream
basic_stringstream
Array I/O
basic_ispanstream
(C++23)
basic_ospanstream
(C++23)
basic_spanstream
(C++23)
istrstream
(
C++98/26*
)
ostrstream
(
C++98/26*
)
strstream
(
C++98/26*
)
Synchronized Output
basic_osyncstream
(C++20)
Types
streamoff
streamsize
fpos
Error category interface
iostream_category
(C++11)
io_errc
(C++11)
C-style I/O
Types and objects
FILE
fpos_t
stdin
stdout
stderr
Functions
File access
fopen
freopen
fclose
fflush
fwide
setbuf
setvbuf
Direct input/output
fread
fwrite
Unformatted input/output
fgetc
getc
fgets
fputc
putc
fputs
getchar
gets
(until C++14)
putchar
puts
ungetc
fgetwc
getwc
fgetws
fputwc
putwc
fputws
getwchar
putwchar
ungetwc
Formatted input
scanf
fscanf
sscanf
vscanf
vfscanf
vsscanf
(C++11)
(C++11)
(C++11)
wscanf
fwscanf
swscanf
vwscanf
vfwscanf
vswscanf
(C++11)
(C++11)
(C++11)
Formatted output
printf
fprintf
sprintf
snprintf
(C++11)
vprintf
vfprintf
vsprintf
vsnprintf
(C++11)
wprintf
fwprintf
swprintf
vwprintf
vfwprintf
vswprintf
File positioning
ftell
fgetpos
fseek
fsetpos
rewind
Error handling
clearerr
feof
ferror
perror
Operations on files
remove
rename
tmpfile
tmpnam
定义于头文件
int
printf
(
const
char
*
format, ...
)
;
(1)
int
fprintf
(
std::
FILE
*
stream,
const
char
*
format, ...
)
;
(2)
int
sprintf
(
char
*
buffer,
const
char
*
format, ...
)
;
(3)
int
snprintf
(
char
*
buffer,
std::
size_t
buf_size,
const
char
*
format, ...
)
;
(4)
(C++11 起)
从给定位置加载数据,将其转换为等效字符串形式,并将结果写入多种输出目标。
1)
将结果写入
stdout
。
2)
将结果写入文件流
stream
。
3)
将结果写入字符字符串
buffer
。
4)
将结果写入字符字符串
buffer
中。最多写入
buf_size
-
1
个字符。生成的字符字符串将以空字符结尾,除非
buf_size
为零。如果
buf_size
为零,则不会写入任何内容且
buffer
可为空指针,但返回值(不包含空终止符的待写入字节数)仍会被计算并返回。
如果对
sprintf
或
snprintf
的调用导致在重叠的对象之间进行复制,则行为是未定义的(例如
sprintf
(
buf,
"%s text"
, buf
)
;
)。
目录
1
参数
2
返回值
3
备注
4
示例
5
参见
参数
stream
-
要写入的输出文件流
buffer
-
要写入的字符串指针
buf_size
-
最多可写入
buf_size
-
1
个字符,外加空终止符
format
-
指向空终止多字节字符串的指针,用于指定数据解析方式
...
-
指定要打印数据的参数。若在
默认参数提升
后,任何参数不符合对应转换说明符期望的类型(期望类型为提升后的类型或与提升类型兼容的类型),或参数数量少于
format
所需数量,则行为未定义。若参数数量多于
format
所需数量,多余参数会被求值并忽略
format
字符串由普通字节字符(除了
%
外)和转换说明组成。普通字节字符会原样复制到输出流中。每个转换说明具有以下格式:
引导性的
%
字符。
(可选)
一个或多个用于修改转换行为的标志:
-
:转换结果在字段内左对齐(默认为右对齐)。
+
:有符号转换的结果前始终附加符号(默认情况下仅当结果为负数时前置减号)。
space
:如果有符号转换的结果不以符号字符开头或为空时,将在结果前添加空格。若存在
+
标志则此标志被忽略。
#
:执行转换的
替代形式
。具体效果参见下表,否则行为未定义。
0
:对于整数和浮点数转换,使用前导零而非
space
字符填充字段。对于整数,若显式指定精度则此标志被忽略。其他转换使用此标志将导致未定义行为。若存在
-
标志则此标志被忽略。
(可选)
整数值或
*
用于指定最小字段宽度。当需要时,默认会在右侧对齐时左侧填充
空格
字符,或在左侧对齐时右侧填充。若使用
*
时,宽度由
int
类型的附加参数指定,该参数出现在待转换参数之前(若提供了精度参数,则出现在精度参数之前)。若参数值为负数,将导致指定
-
标志并采用正数字段宽度(注意:此为最小宽度:值永远不会被截断)。
(可选)
.
后接整数或
*
,或两者皆无,用于指定转换的
精度
。当使用
*
时,精度由
int
类型的附加参数指定,该参数出现在待转换参数之前,但在提供最小字段宽度的参数(若存在)之后。若该参数值为负,则被忽略。若未使用数字或
*
,则精度默认为零。具体精度效果请参阅下表。
(可选)
长度修饰符
用于指定参数的大小(与转换格式说明符结合使用时,可指定对应参数的类型)。
转换格式说明符。
以下格式说明符可用:
转换
说明符
说明
期望
参数类型
长度修饰符→
hh
h
无
l
ll
j
z
t
L
仅自 C++11 起可用→
是
是
是
是
是
%
输出字面量
%
。完整转换规范必须为
%%
。
不适用
不适用
不适用
不适用
不适用
不适用
不适用
不适用
不适用
c
写入
单个字符
。
参数首先被转换为
unsigned
char
。
若使用
l
修饰符,参数会先通过
%ls
格式以
wchar_t
[
2
]
参数形式转换为字符字符串。
N/A
N/A
int
std::wint_t
N/A
N/A
N/A
N/A
N/A
s
写入
字符串
。
参数必须是指向字符数组首元素的指针。
精度
指定要写入的最大字节数。若未指定
精度
,则写入直到首个空终止符(不包含该终止符)前的所有字节。
若使用
l
限定符,则参数必须是指向
wchar_t
数组首元素的指针,该数组会通过调用
std::wcrtomb
(使用零初始化的转换状态)转换为 char 数组。
N/A
N/A
char
*
wchar_t
*
N/A
N/A
N/A
N/A
N/A
d
i
将
有符号整数
转换为十进制表示形式
[-]dddd
。
精度
指定要显示的最小数字位数。默认精度为
1
。
如果转换后的值和精度均为
0
,则转换结果不产生任何字符。
对于
z
修饰符,期望的参数类型是
std::size_t
的有符号版本。
signed
char
short
int
long
long
long
std::intmax_t
※
std::ptrdiff_t
N/A
o
将
无符号整数
转换为八进制表示形式
oooo
。
精度
指定要显示的最小数字位数。默认精度为
1
。
如果转换后的值和精度均为
0
,则转换结果不产生任何字符。
在
替代实现
中,如需写入一个前导零,则会按需增加精度。此时若转换后的值和精度均为
0
,则会写入单个
0
。
unsigned
char
unsigned
short
unsigned
int
unsigned
long
unsigned
long
long
std::uintmax_t
std::size_t
std::ptrdiff_t
的无符号版本
N/A
x
X
将
无符号整数
转换为十六进制表示形式
hhhh
。
对于
x
转换,使用字母
abcdef
。
对于
X
转换,使用字母
ABCDEF
。
精度
指定要显示的最小数字位数。默认精度为
1
。
如果转换值和精度均为
0
,则转换结果不产生任何字符。
在
替代实现
中,如果转换值非零,则会在结果前添加
0x
或
0X
前缀。
N/A
u
将
unsigned integer
转换为十进制表示形式
dddd
。
Precision
指定要显示的最小数字位数。
默认精度为
1
。
如果转换值和精度均为
0
,则转换结果不产生任何字符。
N/A
f
F
(C++11)
将
浮点数
转换为
[-]ddd.ddd
风格的十进制表示法。
精度
指定小数点后要显示的确切位数。
默认精度为
6
。
在
替代实现
中,即使没有后续数字也会写入小数点字符。
关于无穷大和非数字转换风格的说明请参阅
notes
。
N/A
N/A
double
double
(C++11)
N/A
N/A
N/A
N/A
long
double
e
E
将
浮点数
转换为十进制指数表示法。
对于
e
转换样式,使用格式
[-]d.ddd
e
±dd
。
对于
E
转换样式,使用格式
[-]d.ddd
E
±dd
。
指数部分至少包含两位数字,仅在必要时使用更多位数。
如果值为
0
,则指数也为
0
。
精度
指定小数点后应显示的确切位数。
默认精度为
6
。
在
替代实现
中,即使没有后续数字也会写入小数点字符。
关于无穷大和非数值的转换样式,请参阅
说明
。
N/A
N/A
N/A
N/A
N/A
N/A
a
A
(C++11)
将
浮点数
转换为十六进制指数表示法。
对于
a
转换样式,使用
[-]
0x
h.hhh
p
±d
格式。
对于
A
转换样式,使用
[-]
0X
h.hhh
P
±d
格式。
如果参数是规范化的浮点数值,首位十六进制数字不会为
0
。
如果值为
0
,指数也为
0
。
精度
指定十六进制小数点后应显示的确切位数。
默认精度足以精确表示该值。
在
替代实现
中,即使后面没有数字也会写入十进制小数点字符。
关于无穷大和非数值的转换样式,请参阅
说明
。
N/A
N/A
N/A
N/A
N/A
N/A
g
G
将
浮点数
根据数值和
精度
转换为十进制或十进制指数表示法。
对于
g
转换样式,将使用
e
或
f
样式进行转换。
对于
G
转换样式,将使用
E
或
f
(C++11前)
F
(C++11起)
样式进行转换。
令
P
等于精度(若精度非零)、
6
(若未指定精度)或
1
(若精度为
0
)。若使用
E
样式转换的指数为
X
:
若
P > X ≥ −4
,则使用
f
或
F
(C++11起)
样式转换,精度为
P − 1 − X
。
否则使用
e
或
E
样式转换,精度为
P − 1
。
除非要求
替代表示
,否则会移除末尾零,且当没有小数部分时移除小数点。
无穷大与非数值的转换样式参见
说明
。
N/A
N/A
N/A
N/A
N/A
N/A
n
返回此函数调用
目前已写入的字符数
。
结果将
写入
到参数所指向的值中。
格式说明符不得包含任何
标志
、
字段宽度
或
精度
。
对于
z
修饰符,预期参数类型为
S
*
,其中
S
是
std::
size_t
的有符号版本。
signed
char
*
short
*
int
*
long
*
long
long
*
std::intmax_t
*
※
std::ptrdiff_t
*
N/A
p
写入实现定义的字符序列,用于定义
pointer
(指针)。
N/A
N/A
void
*
N/A
N/A
N/A
N/A
N/A
N/A
备注
浮点数转换函数将无穷大转换为
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
。由于可变参数函数调用时会发生提升,传递这些类型的值是安全的。
固定宽度字符类型(
std::int8_t
等)的正确转换规范定义在头文件
中(尽管
PRIdMAX
、
PRIuMAX
等等同于
%jd
、
%ju
等)。
内存写入转换说明符
%n
是安全漏洞的常见目标,当格式字符串依赖于用户输入时尤其如此。
每个转换说明符操作后存在一个
序列点
;这允许将多个
%n
结果存储到同一变量中,或者在极端情况下,在同一调用中打印被先前
%n
修改的字符串。
如果转换规范无效,则行为未定义。
返回值
1,2)
成功时写入的字符数量,若出现错误则返回负值。
3)
成功时写入的字符数(不包含终止空字符),若发生错误则返回负值。
4)
若操作成功时,本应写入足够大缓冲区的字符数量(不包含终止空字符);若发生错误,则返回负值。因此,当且仅当返回值非负且小于
buf_size
时,(以空字符终止的)输出内容已完全写入。
注释
POSIX 规范
规定,在发生错误时需设置
errno
。该规范还定义了额外的转换说明符,其中最值得注意的是支持参数重排序功能(
n$
紧接在
%
后表示第
n
个
参数)。
调用
std::snprintf
时,将
buf_size
设为零并将
buffer
设为空指针(当双重调用的开销可接受时)可用于确定容纳输出所需的缓冲区大小:
auto fmt = "sqrt(2) = %f";
int sz = std::snprintf(nullptr, 0, fmt, std::sqrt(2));
std::vector
std::sprintf(buf.data(), fmt, std::sqrt(2)); // 确保适配
示例
运行此代码
#include
#include
#include
#include
int main()
{
const char* s = "Hello";
std::printf("Strings:\n"); // same as std::puts("Strings:");
std::printf("\t[%10s]\n", s);
std::printf("\t[%-10s]\n", s);
std::printf("\t[%*s]\n", 10, s);
std::printf("\t[%-10.*s]\n", 4, s);
std::printf("\t[%-*.*s]\n", 10, 4, s);
std::printf("Characters:\t%c %%\n", 'A');
std::printf("Integers:\n");
std::printf("\tDecimal: \t%i %d %.6i %i %.0i %+i %i\n",
1, 2, 3, 0, 0, 4,-4);
std::printf("\tHexadecimal:\t%x %x %X %#x\n",
5,10,10, 6);
std::printf("\tOctal: \t%o %#o %#o\n",
10, 10, 4);
std::printf("Floating point:\n");
std::printf("\tRounding:\t%f %.0f %.32f\n", 1.5, 1.5, 1.3);
std::printf("\tPadding:\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5);
std::printf("\tScientific:\t%E %e\n", 1.5, 1.5);
std::printf("\tHexadecimal:\t%a %A\n", 1.5, 1.5);
std::printf("\tSpecial values:\t0/0=%g 1/0=%g\n", 0.0/0.0, 1.0/0.0);
std::printf("Variable width control:\n");
std::printf("\tright-justified variable width: '%*c'\n", 5, 'x');
int r = std::printf("\tleft-justified variable width : '%*c'\n", -5, 'x');
std::printf("(the last printf printed %d characters)\n", r);
std::printf("Fixed-width types:\n");
std::uint32_t val = std::numeric_limits
std::printf("\tLargest 32-bit value is %" PRIu32 " or %#" PRIx32 "\n",
val, val);
}
可能的输出:
字符串:
[ Hello]
[Hello ]
[ Hello]
[Hell ]
[Hell ]
字符: A %
整数:
十进制: 1 2 000003 0 +4 -4
十六进制: 5 a A 0x6
八进制: 12 012 04
浮点数:
舍入: 1.500000 2 1.30000000000000004440892098500626
填充: 01.50 1.50 1.50
科学计数法: 1.500000E+00 1.500000e+00
十六进制: 0x1.8p+0 0X1.8P+0
特殊值: 0/0=-nan 1/0=inf
可变宽度控制:
右对齐可变宽度: ' x'
左对齐可变宽度: 'x '
(最后一个printf打印了41个字符)
固定宽度类型:
最大的32位值是 4294967295 或 0xffffffff
另请参阅
wprintf
fwprintf
swprintf
将格式化宽字符输出打印到
stdout
、文件流或缓冲区
(函数)
vprintf
vfprintf
vsprintf
vsnprintf
(C++11)
使用可变参数列表将格式化输出打印到
stdout
、文件流或缓冲区
(函数)
fputs
将字符串写入文件流
(函数)
scanf
fscanf
sscanf
从
stdin
、文件流或缓冲区读取格式化输入
(函数)
to_chars
(C++17)
将整数或浮点数值转换为字符序列
(函数)
(C++23)
使用参数的
格式化
表示形式打印到
stdout
或文件流
(函数模板)
println
(C++23)
与
std::print
相同,但每次打印后都会附加换行符
(函数模板)
C 文档
关于
printf
、
fprintf
、
sprintf
、
snprintf