printf函数接口的解读

来源:互联网 发布:outlook邮箱域名是什么 编辑:程序博客网 时间:2024/05/22 15:52

printf函数接口的解读

本文写的是关于printf()函数接口的所支持的长度修饰符和能够支持的前缀内容。在文章中详细罗列了关于函数接口所支持的类型和内容,同时将该函数接口所支持的参数说明也详细的罗列了出来,能够让阅读者比较方便的阅读该接口内容。

1、接口格式

printf()函数接口的一般格式为:

%(flag)(width)(.prec)[ length ] type                                              (1)

(1)格式为ISO格式,一般情况下我们默认使用该格式,但也不排除例外情况。比如说微软公司在这个方面中给出了(2)的定义:

%(flag)(width)(.prec)[size] type                                                  (2)

从内容的角度来说,两者是一样的只是给出的名称不同。但是从功能上来说,由于定义的不一样,所以在使用的时候可能会产生不兼容现象,所以需要稍微注意一点。下面将对该用法进行详细的说明。

2、type类型

type类型整个定义中都是比较重要内容,所以如何理解type类型是比较重要的。在ISO和微软自定的中又有一些略微不同的地方。

(1)I(大写的 i)、I32、I64 和 w 参数大小修饰符前缀是 Microsoft 扩展,且不符合 ISO C。

(2)intmax_t最大宽度的有符号整数类型;size_t无符号整数类型;pthrdiff_t 有符号整数类型。

表1:ISO标准和微软自定义

参数类型

使用前缀

类型说明符号

signed char

unsigned char

signed char*

hh

d、i

o、u、x 或 X

n

short int

short unsigned int

short *

h

d、i

n

int

char*

int

unsigned int

double

int*

void *

none

c

s

d、i

o、u、x 或 X

f、F、e、E、a、A、g、G

n

p

wint_t

wchar_t*

long int

unsigned long int

double

long*

l

c

s

d、i

o、u、x 或 X

f、F、e、E、a、A、g、G

n

long long int

unsigned long long int

long long*

ll

d、i、o、u、x 或 X

n

intmax_t

uintmax_t

intmax_t*

j

d、i、o、u、x 或 X

n

size_t

有符号size_t*

z

d、i、o、u、x 或 X

n

ptrdiff_t

ptrdiff_t

t

d、i、o、u、x 或 X

n*

long double

l(小写的 L)或 L

a、A、e、E、f、F、g 或 G

__int32

unsigned __int32

I32

d、i、o、u、x 或 X

__int64

unsigned __int64

I64

d、i、o、u、x 或 X

单字节字符

h

c 或 C

宽字符

l(小写的 L)或 w

c 或 C

单字节字符串

h

s、S 或 Z

宽字符字符串

l(小写的 L)或 w

s、S 或 Z

ptrdiff_t

I(大写的 i)

d、i、o、u、x 或 X

size_t

I(大写的 i)

d、i、o、u、x 或 X

intmax_t

uintmax_t

I(大写的 i)

d、i、o、u、x 或 X

表二:type类型说明

类型字符

含义

解释

c

字符

输出单字节字符;与wprintf 函数一起使用时,指定宽字符。

C

字符

输出宽字节字符

s

字符串

输出字符串;显示第一个空字符之前内容或达到精度值时的内容;与wprintf函数一起使用时,指定宽字符字符串。

S

字符串

指定宽字符字符串;与 wprintf 函数一起使用时,指定单字节或多字节字符串。

d / i

整数

接受整数值并将它表示为有符号的十进制整数

o

整数

无符号8进制整数(不输出前缀0)

u

整数

无符号10进制整数

X / x

整数

无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF(不输出前缀0x)

E / e

浮点

转换为一个浮点型的十进制指数计数法,此处"e"的大小写代表在输出时用的“e”的大小写

F / f

浮点

转换为一个浮点样式的十进制数

G / g

浮点

有符号的值将显示为f或e格式,取其中对于给定的值和精度更为精简一个。 仅当值的指数小于 -4 或大于等于 precision 参数时,才使用 e 格式。 截去尾随零,仅当后跟一个或多个数字时,才会显示小数点

A /a

浮点

转换为一个浮点型的十六进制记法(前者用大写字面表示,后者用小写字母表示)

n

指向整数的指针

返回对函数的此调用迄今为止写入的字符数。结果被写入到参数所指向的值。

p

指针类型

将自变量显示为十六进制数中的地址

Z

ANSI_STRING或UNICODE_STRING结构

将ANSI_STRING或UNICODE_STRING结构的地址作为参数传递时,会显示包含在由结构的Buffer字段指向的缓冲区中的字符串。使用w的大小修饰符前缀指定 UNICODE_STRING 参数,例如 %wZ。结构的 Length 字段必须设置为字符串的长度(以字节为单位)。结构的MaximumLength字段必须设置为缓冲区的长度(以字节为单位)。

在上面的两个表格中,表2是type类型的说明,表1是类型对应的输出类型,通过一一对应来达到输出内容的目的。

3、flags

转换规范中的第一个可选字段包含标志指令、零个或者多个标志字符,用于指定输出对齐方式以及控制符号、空白、前导零、小数点以及八进制和十六进制前缀输出等等。在转换的时候可能会出现多个标志指定,并且标志字符可能会按下面的顺序出现。

表3:标志字符的含义及内容

字符

字符名称

作用

-

减号

在给定的字段宽度内左对齐。默认右对齐。

+

加号

有符号转换的符号始终前置于转换结果(默认结果前置负号仅当它为负)

0

数字0

对于整数和浮点数转换,使用前导零代替空格字符填充域。对于整数,若显式指定精度,则忽略此标签。对于其他转换,使用此标签导致未定义行为。如果0和-同时出现,0则将被忽略。默认不填充0

 

空格

如果输出值为有符号的正值,则使用空白作为其前缀。如果空白和 +标志同时出现,空白则将被忽略。默认不显示

#

井号

type是o、x、X时,#分别使用 00x0X作为任何非零输出值的前缀。默认不显示空白。

type是e、E、f、g、G时,#强制输出值包含小数点。默认仅当小数点后紧跟数字时,才会显示小数点

type是g、G时,#标志将强制输出值包含小数点,并阻止截断尾随零。默认仅当小数点后紧跟数字时,才会显示小数点。

type是与c、d、i、u或s一起使用时,则将被忽略。默认截断尾随零。

4、width

在转换的时候,可选宽度规范字段出现在任何标志字符之后。宽度参数是控制输出最小字符数的非负整数(十进制)。如果输出内容中的字符数小于指定宽度,则将在输出内容的左侧或者右侧添加空白,直到达到最小宽度。

如果宽度规范是一个星号 (*),则参数列表中的 int 参数将提供此值。宽度参数必须先于在参数列表中要设置其格式的值。(注意:这是最小宽度:值决不会被截断)。

例如:

printf("%*d",a,b);

其中a作为b的输出宽度控制。其实也就是*的替换功能了,正是由于*的替换功能结合%md的宽度控制,替换之后具体怎么输出的规则就和宽度控制的规则一样了.

正常情况下:

printf("%*d",2,123)

输出内容为123。在这里"2"的作用相当于%2d,由于"123"的位数超过2位,原样输出,同时默认右对齐,所以看起来没有什么大的变化。

5、prec

在转换格式中,第三个可选字段是精度规范。它包含一个句点(.),后跟一个非负十进制整数,指定字符串字符数、小数位数或要输出的有效数字位数,具体取决于转换类型。

与宽度规范不同的是,精度规范可能导致输出值截断或浮点值舍入。如果将精度指定为 0 并且要转换的值为0,则结果为无字符输出。

当type=d,o,u,x时,没有影响;

type=e,E,f时,不显示小数点

n(n=1,2,3...)

当type=e,E,f时表示的最大小数位数;

type=其他,表示显示的最大宽度

表4:精度对类型的影响

类型

作用含义

a、A

精度指定此点后的数字位数。默认精度为 13。如果精度为0,除非使用了#标志,否则不会打印小数点。

c、C

精度不产生任何影响。打印字符。

d、i、o、u、x、X

精度指定要打印的最小数字位数。如果参数中的数字位数小于精度,则将在输出值的左侧使用零进行填充。数字位数超过精度时,值将不会被截断。默认精度为1。

e、E

精度指定此小数点后要打印的数字位数。打印的最后一位数舍入。默认精度为6,如果精度为0,或者如果句点(.)后面不跟数字,则不会打印小数点。

f、F

精度值指定此小数点后的数字位数。如果出现小数点,则在它之前至少会显示一个数字。该值舍入为适当数量的数字。默认精度为6。如果精度为0,或者如果句点(.)后面不跟数字,则不会打印小数点。

g、G

精度指定打印的最大有效位数。打印六个有效位数,并且任何尾随零都会被截断。

s、S

精度指定要打印的最大字符数。 不会打印超过精度的字符。在遇到 null 字符之前不会打印字符。

6、length

表5:长度符

 

specifier

length

d  i

u o x X

FFeEgGaA

c

s

p

n

(none)

int

usigned int

double

int

char*

void*

int*

hh

signed char

unsigned char

 

 

 

 

signed char*

h

short int

unsigned short int

 

 

 

 

short int*

l

long int

unsigned long int

 

wint_t

wchar_t*

 

long int*

ll

long long int

unsigned long long int

 

 

 

 

long long int*

j

intmax_t

uintmax_t

 

 

 

 

intmax_t*

z

size_t

size_t

 

 

 

 

size_t*

t

ptrdiff_t

ptrdiff_t

 

 

 

 

ptrdiff_t*

L

 

 

long double

 

 

 

 

表6:各类型格式取值范围

类型

位数

格式

值的范围

近似

精确

字符

8

signed

-128~127

unsigned

0~255

16

unsigned

0~65535

整型

16

signed

± 3.27*10^4

-32767~32767

unsigned

0~6.55*10^4

0~65535

32

signed

± 2.14*10^9

-2,147,483,647~2,147,483,647

unsigned

0~4.29*10^9

0~4,294,967,295

64

signed

± 9.22*10^18

9,223,372,036,854,775,807~9,223,372,036,854,775,807

unsigned

0~1.84*10^19

0~18,446,744,073,709,551,615

浮点

32

float

± 3.4*10^± 38

最小次正规:± 1.401,298,4*10^-47

最小正规:± 1.175,494,3*10^-38

最大:± 3.402,823,4*10^38

64

double

± 1.7*10^± 308

最小次正规:± 4.940,656,458,412*10^-324

最小正规:± 2.225,073,858,507,201,4*10^-308

最大:± 1.797,693,134,862,315,7*10^308

7、size[7]

在转换过程中中,大小字段是类型转换说明符的参数长度修饰符。

大小字段作为类型字段(hh、h、j、l(小写的 L)、L、ll、t、w、z、I(大写的i)、I32和I64)的前缀,根据它们修饰的转换说明符,指定对应参数的“大小”(长型或短型、32 位或64位、单字节字符或宽字符)。

大小字段对于某些参数类型是可选的。未指定任何大小前缀时,格式化程序使用整数参数(例如,有符号或无符号的 char、short、int、long 和枚举类型)作为32位int类型,而使用float、double 和long double浮点参数作为64位double类型。这与变量自变量列表的默认自变量提升规则相匹配。在32位和64位系统上,64位整数参数的转换规范必须包含ll或I64大小前缀。否则,格式化程序的行为是不明确的。特定于Microsoft的I(大写的i)参数大小修饰符可处理宽度可变的整数参数。

8、其他

转义字符:这些转义序列在字符串中会被自动转换为相应操作命令

字符

意义

\"

双引号

\\

反斜杠

\a

提示;提醒

\b

退格

\c

输出单个字符

\e

指数输出

\f

换页

\n

换行

\r

回车

\t

水平制表(跳到下一个TAB位置)

\v

垂直制表

\NNN(例如:\024)

ASCII字符(OCX)

\xHH(例如:\020)

ASCII字符(HEX)

\uHHHH(16进制数)

宽字符(2字符HEX)

9、C11函数接口说明

(1)、int fprintf_s(FILE *restrictstream,const char *restrict format, ...);

说明:stream和format都不应该为空指针,%n不会出现在指向字符串的格式中。%s说明符在fprintf_s的对应的任何参数不得为空指针

描述:fprintf_s函数除开限制条件之外等同于fprintf

返回:函数会输入的字符数,如果出现错误情况,如:输入错误、编码错误、超时等等,则报错。

案例:

FILE*fp = NULL;

char*s = "that is a good new";

fopen_s(&fp,"date.txt", "wt+");

fprintf(fp,"%s\n", s);

(2)、int printf_s(const char *restrictformat,……);

说明:format格式不能为空,在format中不能存在转换指定符号%n,任何对应%s的参数不能为空指针

描述:printf_s函数除开限制条件之外,几乎等同与printf

返回值:printf_s函数返回送回的字符串,或者负数。如果出现输出错误,编码错误或者运行时间限制则报错。

案例:

char*e = "hello,world!";

printf_s("%s%d\n",e, 10);

(3)、intsprintf_s(char *restrict  s, rsize_t  n, const char * restrict  format,…..);

说明:s和format都不能为空。n不得等于零也不能比RSIZE_MAX大。要求的字符结果写入s指向的数组中,不得大于n否则会报错。format中不能存在转换指定符%n。任何一个对应%s的参数是空指针。在任何一个字符串或者字符转换指定符只能怪出现编码错误的时候会报错。注意:当s不是空指针,n大于0小于RSIZE_MAX的时候,则sprintf_s函数将s[0]设置为空字符。

描述:sprintf_s函数在除开参数n约束条件外等同与sprintf()。sprintf_s函数和snprintf_s略微有些不同,sprintf_s处理数组s比较大

返回值:不发生错误情况的时候,函数调用结返回写入字符内容的数组,并不计终止空字符。如果编码错误sprintf_s返回做一个负值。如果在运行的时候检测到错误情况,则sprintf_s返回零。

案例:

char buffer[1024] = { 0 };

char e[12] = "hello world";

sprintf_s(buffer,12, "%s", e);

(4)、int snprintf_s(char * restrict s, rsize_t  n; const char *restrict  format, …….)

说明:s和format都不能为空。n不得等于零也不能比RSIZE_MAX大。要求的字符结果写入s指向的数组中,不得大于n否则会报错。format中不能存在转换指定符%n。任何一个对应%s的参数是空指针。在任何一个字符串或者字符转换指定符只能怪出现编码错误的时候会报错。注意:当s不是空指针,n大于0小于RSIZE_MAX的时候,则sprintf_s函数将s[0]设置为空字符。

描述:snprintf_s函数除开约束条件外等同于snprintf函数。snprintf_s函数与sprintf_s不同,将截断结果以适合s指向的数组。返回值是源字符串字符数量。

返回值:snprintf_s函数返回已经存在的字符数,不计算终止空字符,如果程序报错,则返回一个负数。当且仅当返回值是非负数且小于n的时,空终止输出完全写入。

案例:

char buffer[1024] = { 0 };

int a = 11;

int s = _snprintf_s(buffer,a,15"%s","helloworld");

总结:

printf()格式转换的一般形式:%(flag) (width) (prec)length type

% -  0  m.n  length  type

1、"%":表示格式说明起始符号,不可缺少;

2、"-":有"-"表示左对齐输出,如没有则表示右对齐输出;

3、"0":有0表示指定空位用0补充,如没有这表示空位不填,空格表示;

4、m.n:m 指域宽,即对应的输出项在输出设备上所占的字符数。 N 指精度。用于说明输出的实型数的小数位数。为指定n时,隐含的精度为 n=6 位

5、length长度符号,指定想要的长度修饰符来输出想要的内容格式

 

格式字符:指定输出项的数据类型和输出格式。

1、%d:按照整型数据的实际长度输出

%md:m为指定输出字段的宽度,如果数据的位数小于m,则左端补以空格,若大于m,则按实际位数输出

%ld:输出长整型数据

2、o格式:以无符号八进制形式输出整数。对长整型可以用%lo 格式输出。同样可以用%mo格式输出。(o、x、u都可以这么用)

3、c格式:输出一个字符;

4、s格式:用来输出一个字符串:

%s:只是输出字符内容,不输出其他;

%ms输出字符串占m个,如果字符串本身长度大于m,则将字符串内容全部输出;若小于m,则在左则补空格;

%-ms:字符串长度小于m,在m列范围nei,字符向左靠齐,右补空格;

%m.ns:输出占m列,但只取字符串中左端的n个字符,这n个字符输出在m列的右侧,左边补齐空格。

%-m.n:n个字符输出在m列范围的左侧,右补齐空格。如果n>m。则自动取n值,即保证n个字符正常输出。

5、%f:输出实数(包括单双精度),以小数形式输出。

%f:不指定宽度,整数部分全部输出并且输出6位小数。

%m.nf:输出共m个数,其中小数有n为,如果数值宽度小于m左端补齐空格

%-m.nf:输出攻占m个数,其中n为小数,如果数值宽度小于m有段补齐空格

6、%e:以指数行书输出实数。

%e:数字部分输出6位,指数部分占5位后者4位

%m.ne和%-m.ne:n指的是数据的数字部分的小数位数,m表示整数输出数据所占据的宽度。

7、g格式:自动选 f 格式或 e 格式中较短的一种输出,且不输出无意义的零。