非常教程

C参考手册

文件输入/输出 | File input/output

printf_s

Defined in header <stdio.h>

(1)

​int printf( const char *format, ... );​

(until C99)

​int printf( const char *restrict format, ... );​

(since C99)

(2)

int fprintf( FILE *stream, const char *format, ... );

(until C99)

int fprintf( FILE *restrict stream, const char *restrict format, ... );

(since C99)

(3)

int sprintf( char *buffer, const char *format, ... );

(until C99)

int sprintf( char *restrict buffer, const char *restrict format, ... );

(since C99)

int snprintf( char *restrict buffer, int bufsz, const char *restrict format, ... );

(4)

(since C99)

int printf_s(const char *restrict format, ...);

(5)

(since C11)

int fprintf_s(FILE *restrict stream, const char *restrict format, ...);

(6)

(since C11)

int sprintf_s(char *restrict buffer, rsize_t bufsz, const char *restrict format, ...);

(7)

(since C11)

int snprintf_s(char *restrict buffer, rsize_t bufsz, const char *restrict format, ...);

(8)

(since C11)

从给定的位置加载数据,将它们转换为字符串等价物并将结果写入各种接收器。

1)将结果写入输出流stdout

2)将结果写入输出流stream

3)将结果写入字符串buffer。如果要写入的字符串(加上终止的空字符)超过了指向的数组的大小,则行为未定义buffer

4)将结果写入字符串buffer。最多bufsz- 写入1个字符。结果字符串将以空字符结尾,除非bufsz为零。如果bufsz为零,则不会写入任何内容,并且buffer可能是空指针,但返回值(将写入的字节数)仍然会计算并返回。

5-8)与(1-4)相同,只是在运行时检测到以下错误并调用当前安装的约束处理函数:

  • 转换说明符%n存在于format
  • 任何对应的参数%s都是空指针
  • format或者buffer是空指针
  • bufsz 是零或大于 RSIZE_MAX
  • 编码错误出现在任何字符串和字符转换说明符中
  • sprintf_s仅限于),要存储的字符串buffer(包括结尾空值)将被超出bufsz

由于所有的边界检查功能,printf_sfprintf_ssprintf_s,和snrintf_s仅保证可供如果__STDC_LIB_EXT1__由实现所定义,并且如果用户定义__STDC_WANT_LIB_EXT1__的整数常数1,包括之前<stdio.h>

参数

-

输出文件流写入

缓冲

-

指向要写入的字符串的指针

bufsz

-

最多bufsz - 可能会写入1个字符,再加上空终止符

格式

-

指向以空字符结尾的多字节字符串的指针,指定如何解释数据。

格式字符串由普通的多字节字符(除外%)组成,它们被不变地复制到输出流和转换规范中。每个转换规范具有以下格式:

介绍%人物

(可选)一个或多个修改转换行为的标志:

-:转换的结果在字段内左对齐(默认情况下它是右对齐的)

+:带符号转换的符号总是预设为转换结果的前缀(默认情况下结果前面为减号,仅当它为负值时)

空格:如果签名转换的结果不是以符号字符开头,或者是空的,则空格会预设为结果。如果+标志存在,它将被忽略。

#:执行转换的替代形式。请参阅下表以了解确切的效果,否则行为未定义。

0:对于整数和浮点数转换,前导零用于填充字段而不是空格字符。对于整数,如果明确指定了精度,它将被忽略。对于使用此标志的其他转换会导致未定义的行为。如果-标志存在,它将被忽略。

(可选)整数值或*指定最小字段宽度。如果需要,结果会填充空格字符(默认情况下),右侧对齐时填充空白字符,左侧填充右侧填充。在使用的情况下*,宽度由类型的附加参数指定int。如果参数的值是负数,则结果是-指定的标志和正的字段宽度。(注意:这是最小宽度:该值从不被截断。)

(可选) .后面跟随整数或者*或者既不指定转换的精度。在使用的情况下*,精度由类型的附加参数指定int。如果这个参数的值是负数,它将被忽略。如果既不使用数字也不*使用,则精度取为零。请参阅下表以了解精确度的确切影响。

(可选) 长度修饰符,用于指定参数的大小

转换格式说明符

以下格式说明符可用:

转换

说明

参数类型

说明符

长度修饰符

hh

h

(没有)

l

ll

j

z

t

L

(C99)。

(C99)。

(C99)。

(C99)。

(C99)。

%

写文字%。完整的转换规范必须是%%。

N / A

N / A

N / A

N / A

N / A

N / A

N / A

N / A

N / A

c

写一个字符。

N / A

N / A

int

wint_t

N / A

N / A

N / A

N / A

N / A

该论点首先转换为unsigned char。如果使用了l修饰符,则首先将参数转换为字符串,就像通过具有参数的%ls一样wchar_t[2]。

s

写入一个字符串

N / A

N / A

char*

wchar_t*

N / A

N / A

N / A

N / A

N / A

参数必须是指向字符数组的初始元素的指针。Precision指定要写入的最大字节数。如果未指定Precision,则将每个字节写入并不包括第一个空终止符。如果使用了l说明符,则参数必须是指向数组初始元素的指针wchar_t,它将转换为char数组,就像通过调用wcrtomb具有零初始化转换状态一样。

d

将有符号整数转换为十进制表示形式[ - ] dddd。

signed char

short

int

long

long long

intmax_t

签 size_t

ptrdiff_t

N / A

i

精度指定出现的最小位数。默认的精度是1。

如果转换后的值和精度都是​0​没有字符的转换结果。

o

将无符号整数转换为八进制表示oooo。

unsigned char

unsigned short

unsigned int

unsigned long

unsigned long long

uintmax_t

size_t

未签名的版本 ptrdiff_t

N / A

精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。在替代实现中,如果需要,可以增加精度以写入一个前导零。在这种情况下,如果转换后的值和精度都是​0​,​0​写入单个。

x

将无符号整数转换为十六进制表示hhhh。

N / A

X

使用x转换字母abcdef。

使用X转换字母ABCDEF。

精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。在替代实现中, 0x或者0X如果转换后的值不为零,则将其作为结果的前缀。

u

将无符号整数转换为十进制表示形式dddd。

N / A

精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。

f

将浮点数转换为样式[ - ] ddd.ddd中的十进制表示法。

N / A

N / A

double

double(C99)

N / A

N / A

N / A

N / A

long double

F

精度指定小数点后面出现的最小位数。默认的精度是6。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。

e

将浮点数转换为十进制指数符号。

N / A

N / A

N / A

N / A

N / A

N / A

E

对于e转换样式,使用[ - ] d.ddd e±dd。

对于E转换样式,使用[ - ] d.ddd E±dd。

指数至少包含两位数字,只有在必要时才使用更多数字。如果值是​0​,指数也是​0​。精度指定小数点后面出现的最小位数。默认的精度是6。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。

a

将浮点数转换为十六进制指数表示法。

N / A

N / A

N / A

N / A

N / A

N / A

A

对于a转换样式,使用[ - ] 0xh.hhh p±d。

(C99)。

对于A转换样式,使用[ - ] 0Xh.hhh P±d。如果参数不是标准化的浮点值,则

第一个十六进制数字是0。如果值是​0​,指数也是​0​。精度指定小数点后面出现的最小位数。默认精度足以精确表示值。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。

g

根据值和精度将浮点数转换为十进制或十进制指数符号。

N / A

N / A

N / A

N / A

N / A

N / A

G

对于g风格转换的转换与风格e或f将被执行。

对于G风格转换的转换与风格E或F将被执行。

让P等于精度如果非零,6如果没有指定精度,或者1如果精度是​0​。然后,如果具有样式的转换E将具有以下指数X:

如果P> X≥-4,转换是用式f或F和精度P - 1 - X。

否则,转换采用样式e或E精度P - 1。

除非请求替代表示,否则尾随零将被删除,如果没有剩余小数部分,小数点字符也会被删除。对于无穷大和非数字转换风格,请参阅注释。

n

将此调用到目前为止写入的字符数返回给该函数。

signed char*

short*

int*

long*

long long*

intmax_t*

签 size_t*

ptrdiff_t*

N / A

结果写入参数指向的值。规范可能不包含任何标志,字段宽度或精度。

p

写一个实现定义的字符序列来定义一个指针。

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来代替。

即使%c需要int参数,通过char调用可变参数函数时发生的整数提升也是安全的。

对于固定宽度的字符类型(正确的转换规格int8_t,等等)都在头中定义<inttypes.h>还(虽然PRIdMAX,PRIuMAX等是同义词%jd,%ju等)。

内存写入转换说明符%n是安全漏洞的常见目标,其中格式字符串取决于用户输入,并且不受边界检查printf_s函数族的支持。

每个转换说明符的操作之后都有一个序列点 ; 这允许将多个%n结果存储在相同的变量中,或者作为边缘情况,%n在相同的调用中打印由较早修改的字符串。

如果转换规范无效,则行为未定义。

...

-

指定要打印的数据的参数

  • 介绍%人物
  • (可选)一个或多个修改转换行为的标志:
    • -:转换的结果在字段内左对齐(默认情况下它是右对齐的)
    • +:带符号转换的符号总是预设为转换结果的前缀(默认情况下结果前面为减号,仅当它为负值时)
    • 空格:如果签名转换的结果不是以符号字符开头,或者是空的,则空格会预设为结果。如果+存在标志,则忽略它。
    • #:执行转换的替代形式。请参阅下表以了解确切的效果,否则行为未定义。
    • 0:对于整数和浮点数转换,前导零用于填充字段而不是空格字符。对于整数,如果明确指定了精度,它将被忽略。对于使用此标志的其他转换会导致未定义的行为。如果-存在标志,则忽略它。
  • (可选)整数值或*指定最小字段宽度。如果需要,结果会填充空格字符(默认情况下),右侧对齐时填充空白字符,左侧填充右侧填充。在使用的情况下*,宽度由类型的附加参数指定int。如果参数的值是负数,则结果是-指定的标志和正的字段宽度。(注意:这是最小宽度:该值从不被截断。)
    • (可选).后面跟随整数或者*或者既不指定转换的精度。在使用的情况下*精度由类型的附加参数指定int。如果这个参数的值是负数,它将被忽略。如果既不使用数字也不*使用,则精度取为零。请参阅下表以了解精确度的确切影响。
    • (可选)长度修饰符,用于指定参数的大小
    • 转换格式说明符

以下格式说明符可用:

Conversion

说明符说明参数类型长度修饰符 hh(C99)。

h (none) l ll (C99).

j (C99).

z (C99).

t (C99).

L % 写文字%。完整的转换规范必须是%%。N / AN / AN / AN / AN / AN / AN / AN / AN / A c 写入单个字符。该论点首先转换为unsigned char。如果使用了l修饰符,则首先将参数转换为字符串,就像通过具有参数的%ls一样wchar_t[2]

N/A N/A int

wint_t

N / AN / AN / AN / AN / A s 写入字符串参数必须是指向字符数组的初始元素的指针。Precision指定要写入的最大字节数。如果未指定Precision,则将每个字节写入并不包括第一个空终止符。如果使用了l说明符,则参数必须是指向数组初始元素的指针wchar_t,它将转换为char数组,就像通过调用wcrtomb具有零初始化转换状态一样。

N/A N/A char*

wchar_t*

N/A N/A N/A N/A N/A d

i 将有符号的整数转换为十进制表示形式-dddd精度指定出现的最小位数。默认的精度是1

如果转换后的值和精度都是​0​没有字符的转换结果。

signed char

short

int

long

long long

intmax_t

signed size_t

ptrdiff_t

N / A o无符号整数转换为八进制表示oooo精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。在替代实现中,如果需要,可以增加精度以写入一个前导零。在这种情况下,如果转换值和精度都是​0​​0​写入单个。

unsigned char

unsigned short

unsigned int

unsigned long

unsigned long long

uintmax_t

size_t

未签名的版本 ptrdiff_t

N/A x

X无符号整数转换为十六进制表示hhhh。使用x转换字母abcdef

使用X转换字母ABCDEF

精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。在替代实现中, 0x或者0X如果转换后的值不为零,则将其作为结果的前缀。

N / A u无符号整数转换为十进制表示形式dddd精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。

N/A f

F浮点数转换为样式-ddd.ddd中的小数表示法。 精度指定小数点后面出现的最小位数。默认的精度是6。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。

N/A N/A double

`double` (C99) 

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 (C99).

浮点数转换为十六进制指数表示法。对于a转换样式- 使用0xh.hhh p±d

对于A转换样式- 使用0Xh.hhh P±d

0如果参数不是标准化的浮点值,则第一个十六进制数字是。如果值是​0​,指数也是​0​精度指定小数点后面出现的最小位数。默认精度足以精确表示值。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。

N/A N/A N/A N/A N/A N/A g

G根据值和精度浮点数转换为十进制或十进制指数符号。对于风格转换的转换与风格或将被执行。gef

对于G风格转换的转换与风格EF将被执行。

P等于精度如果非零,6如果没有指定精度,或者1如果精度是​0​。然后,如果具有样式的转换E将具有以下指数X

  • 如果P> X≥-4,转换是用式fF和精度P - 1 - X
  • 否则,转换采用样式eE精度P - 1

除非请求替代表示,否则尾随零将被删除,如果没有剩余小数部分,小数点字符也会被删除。对于无穷大和非数字转换风格,请参阅注释。

不适用/不适用/不适用/不适用/ n 返回此函数迄今为止写入的字符数。结果写入参数指向的值。规范可能不包含任何标志字段宽度精度

signed char*

short*

int*

long*

long long*

intmax_t*

signed size_t*

ptrdiff_t*

N / A p 写入一个实现定义的字符序列来定义一个指针。不适用不适用不适用不适用不适用不适用 void* 浮点转换函数将无穷大转换为infinfinity。使用哪一个是实现定义的。

非数字转换为nan或。使用哪一个是实现定义的。nan(char_sequence)

该转换FEGA输出INFINFINITYNAN来代替。

即使%c需要int参数,通过char调用可变参数函数时发生的整数提升也是安全的。

对于固定宽度的字符类型(正确的转换规格int8_t<inttypes.h>还(虽然,等等)都在头定义PRIdMAXPRIuMAX等是同义词%jd%ju等)。

内存写入转换说明符%n是安全漏洞的常见目标,其中格式字符串取决于用户输入,并且不受边界检查printf_s函数族的支持。

每个转换说明符的操作之后都有一个序列点; 这允许将多个%n结果存储在相同的变量中,或者作为边缘情况,%n在同一个调用中打印由较早修改的字符串。

如果转换规范无效,则行为未定义。

 ...   -   arguments specifying data to print   

返回值

1,2)发送到输出流的字符数或负值(如果发生输出错误或编码错误(用于字符串和字符转换说明符))

3)写入的字符数buffer(不包括终止空字符);如果发生编码错误(用于字符串和字符转换说明符),则返回负值

4)buffer如果bufsz被忽略,将被写入的字符数(不包括终止空字符),或者如果编码错误(对于字符串和字符转换说明符)发生,则为负值

5,6)传输到输出流的字符数或负值(如果发生输出错误,运行时间约束违规错误或编码错误)。

7)写入的字符数buffer,不包括空字符(只要buffer不是空指针,bufsz并且不为零且不大于RSIZE_MAX),则不计入空字符,或者在运行时约束违规时为零,编码错误为负值

8)不包括终止空字符的字符数(只要buffer不是空指针并且bufsz不为零且不大于RSIZE_MAX),buffer如果bufsz被忽略,将被写入的字符数或者如果运行时约束违规或编码错误发生

注意

C标准和POSIX指定sprintf当参数与目标缓冲区重叠时,其行为及其变体未定义。例:

sprintf(dst, "%s and %s", dst, t); // <- broken: undefined behavior

POSIX指定该errno设置上的错误。它还指定了额外的转换规范,最显着的是支持参数重新排序(n$紧接在%指示n'th参数之后)。

snprintf使用零bufsz和空指针调用buffer对于确定包含输出所需的缓冲区大小很有用:

const char *fmt = "sqrt(2) = %f";
int sz = snprintf(NULL, 0, fmt, sqrt(2));
char buf[sz + 1]; // note +1 for terminating null byte
snprintf(buf, sizeof buf, fmt, sqrt(2));

snprintf_s, just like snprintf, but unlike sprintf_s, will truncate the output to fit in bufsz-1.

#include <stdio.h>
 
int main(void)
{
    printf("Strings:\n");
    const char* s = "Hello";
    printf("\t.%10s.\n\t.%-10s.\n\t.%*s.\n", s, s, 10, s);
 
    printf("Characters:\t%c %%\n", 65);
 
    printf("Integers\n");
    printf("Decimal:\t%i %d %.6i %i %.0i %+i %u\n", 1, 2, 3, 0, 0, 4, -1);
    printf("Hexadecimal:\t%x %x %X %#x\n", 5, 10, 10, 6);
    printf("Octal:\t%o %#o %#o\n", 10, 10, 4);
 
    printf("Floating point\n");
    printf("Rounding:\t%f %.0f %.32f\n", 1.5, 1.5, 1.3);
    printf("Padding:\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5);
    printf("Scientific:\t%E %e\n", 1.5, 1.5);
    printf("Hexadecimal:\t%a %A\n", 1.5, 1.5);
}

输出:

Strings:
    .     Hello.
    .Hello     .
    .     Hello.
Characters:     A %
Integers
Decimal:        1 2 000003 0  +4 4294967295
Hexadecimal:    5 a A 0x6
Octal:          12 012 04
Floating point
Rounding:       1.500000 2 1.30000000000000004440892098500626
Padding:        01.50 1.50  1.50
Scientific:     1.500000E+00 1.500000e+00
Hexadecimal:    0x1.8p+0 0X1.8P+0

参考

  • C11标准(ISO / IEC 9899:2011):
    • 7.21.6.1 fprintf函数(p:309-316)
    • 7.21.6.3 printf函数(p:324)
    • 7.21.6.5 snprintf函数(p:325)
    • 7.21.6.6 sprintf函数(p:325-326)
    • K.3.5.3.1 fprintf_s函数(p:591)
    • K.3.5.3.3 printf_s函数(p:593-594)
    • K.3.5.3.5 snprintf_s函数(p:594-595)
    • K.3.5.3.6 sprintf_s函数(p:595-596)
  • C99标准(ISO / IEC 9899:1999):
    • 7.19.6.1 fprintf函数(p:274-282)
    • 7.19.6.3 printf函数(p:290)
    • 7.19.6.5 snprintf函数(p:290-291)
    • 7.19.6.6 sprintf函数(p:291)
  • C89 / C90标准(ISO / IEC 9899:1990):
    • 4.9.6.1 fprintf函数
    • 4.9.6.3 printf函数
    • 4.9.6.5 sprintf函数
C

C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。