printf
是C语言的标准输入输出库stdio
提供的库函数,所以在使用它时,需要使用#include <stdio.h>
指令包含stdio.h
头文件。
printf
的功能用以显示格式化字符串的内容,其输入参数必须包括格式化字符串,可能需要提供插入在字符串指定位置的值。格式化字符串由普通字符和转换说明组成,普通字符完全如在格式化字符串中显示的那样打印出来,而转换说明以字符%
开头,表示为插入值提供的占位符。插入的值可以由常量、变量、表达式或带有返回值的函数提供,并且个数没有限制。
printf(格式化字符串, 表达式1, 表达式2, ...)
转换说明
格式化字符串中的转换说明的通用格式是%<A><m><.p><L>X
。
转换说明符
X
为转换说明符,指定了把数值从内部二进制信息打印成字符形式的方式,是必需项。转换说明符列在下表中:
转换说明符 | 含义 |
---|---|
d,i | 插入值类型为有符号整型,转换为十进制形式 |
o,u,x,X | 插入值类型为无符号整型,转换为八机制、十进制和十六进制形式。x 表示以小写字母a-f 显示16进制数,X 表示以A-F 显示十六进制数。 |
f | 插入值类型为double ,转换为十进制形式,小数点放置于正确位置。默认小数点后显示6个数字。 |
e,E | 插入值类型为double ,转换为科学计数法标识。默认小数点后保留6位。选择e ,将e 放在指数前面,如果选择E ,则将E 放在指数前 |
g,G | 插入值类型为double , g 将插入值转换为f 形式或e 形式,G 将插入值转换为f 形式或E 形式。在数值的指数部分小于-4或不小于精度值时,选择e 或E 形式. 不显示尾部的0,小数点仅在后面跟有数字时才显示。 |
c | 插入值类型为无符号字符,输出字符形式 |
s | 插入值类型为字符串。当达到精度或遇到空字符停止写操作 |
p | 插入值类型为指针,转换为可显示格式的void* 型值 |
n | 输入值类型为int型指针,用于存储到本次调用到目前位置输出的字符个数 |
% | 输出字符% |
下面是一个转换说明符的简单例子:
/********************************************
* using_printf.c *
* *
*库函数printf的格式化字符串中的转换说明符 *
********************************************/
#include <stdio.h>
int main()
{
int x1 = 10;
printf("x1: %d\n", x1);
printf("\n");
unsigned int x2 = 180;
printf("x2(八进制): %o\n", x2);
printf("x2(十进制): %u\n", x2);
printf("x2(十六进制): %x\n", x2);
printf("x2(十六进制): %X\n", x2);
printf("\n");
double x3 = 231.0;
printf("x3(十进制): %f\n", x3);
printf("x3(科学计数法): %e\n", x3);
printf("x3(科学计数法): %E\n", x3);
printf("\n");
double x4 = 0.000000123;
printf("x3(f形式): %g\n", x3);
printf("x4(e形式): %g\n", x4);
printf("x4(E形式): %G\n", x4);
double x5 = 5.10000;
printf("x5(去尾部的0): %g\n", x5);
double x6 = 16.00000;
printf("x6(不显示小数点): %g\n", x6);
printf("\n");
char x7 = 'A';
printf("x7: %c\n", x7);
printf("\n");
char x8[] = "Hello World";
printf("x8: %s\n", x8);
printf("\n");
int x9 = 0;
printf("Hello%n\n", &x9);
/*输出Hello,共5个字符, x9中存储5*/
printf("x9: %d\n", x9);
printf("\n");
int x10[] = {1,2,3};
printf("数组x10首地址(指针值): %p\n", x10);
printf("输出百分号:%%\n");
return 0;
}
长短整型长和double
型标识
L
取h,l,L
中的一个,非必需项。当用于显示整数时,字母h
对应的是short
型整数,l
对应的为long
型整数。字母L和e,E,f,g,G
一起使用,对应的输入值为long double
型。
/**********************************
* using_printf_1.c *
* 输出短整型、长整型和长double型 *
**********************************/
#include <stdio.h>
int main()
{
short x1 = 10;
printf("short x1 = %hd\n", x1);
long x2 = 999;
printf("long x2 = %ld\n", x2);
long double x3 = 11.22;
printf("long double x3 = %Lf\n", x3);
return 0;
}
精度
p
表示精度,非必需项,由一个小数点后跟一个整数或字符*
组成。若后跟*
,则p
由printf
函数的下一个参数读入。若仅有小数点,则精度为0。精度的含义因其所修饰的转换说明符的不同而不同。
转换说明符 | 精度p的含义 |
---|---|
d,i,o,u,x,X | 最少数字位数,不足则前面添0 |
e,E,f | 小数点后的数字个数 |
g,G | 最大有效数字位 |
s | 最大字符数 |
不同情况下使用精度选项的例子如下所示:
/********************************************
* using_printf_2.c *
* C语言库函数printf的转换说明中的精度 *
********************************************/
#include <stdio.h>
int main()
{
int x1 = -180;
printf("x1(d): %.5d\n", x1);
printf("x1(i): %.5i\n", x1);
int x2 = 180;
printf("x2(o): %.5o\n", x2);
printf("x2(u): %.5u\n", x2);
printf("x2(x): %.5x\n", x2);
printf("x2(X): %.5X\n", x2);
printf("\n");
int x3 = 180680;
printf("x3(d): %.5d\n", x3);
printf("x3(i): %.5i\n", x3);
int x4 = 180000;
printf("x4(o): %.5o\n", x4);
printf("x4(u): %.5u\n", x4);
printf("x4(x): %.5x\n", x4);
printf("x4(X): %.5X\n", x4);
printf("\n");
double x5 = 10.567891;
printf("x5(f): %.5f\n", x5);
printf("x5(e): %.5e\n", x5);
printf("x5(E): %.5E\n", x5);
printf("\n");
printf("x5(g): %.5g\n", x5);
printf("x5(G): %.5G\n", x5);
printf("\n");
char x6[] = "Hello World!";
printf("x6(s): %.5s\n", x6);
printf("\n");
/*通过*以参数形式输入精度*/
printf("x6(s): %.*s\n", 7, x6);
return 0;
}
最小字符宽度
m
表示最小字符宽度,表示显示的最小字符数量,可选。如果对应的插入数值的字符比m
个字符少,则其在字段内右对齐;如果比m
多,则字符宽度自动扩展为需要的尺寸。
/******************************************
* using_printf_3.c *
* *
* 转换声明中的最小字符宽度与精度 *
******************************************/
#include <stdio.h>
int main()
{
int x1 = 180;
printf("x1(m = 2): %2d\n", x1);
printf("x1(m = 5): %5d\n", x1);
printf("\n");
char x2[] = "Hello World!";
printf("x2(m = 5): %5s\n", x2);
printf("x2(m = 15): %15s\n", x2);
printf("\n");
double x3 = 10.456789;
printf("x3(f, m = 5): %5f\n", x3);
printf("x3(f, m = 10): %10f\n", x3);
printf("\n");
return 0;
}
标志
A
表示标志,用以指定插入数值的显示形式,包括以下5个字符:
标志 | 含义 |
---|---|
- | 在字段内左对齐 |
+ | 以+开头的正符号数 |
空格 | 用空格作为字符宽度内数的前缀 |
# | 输出八进制数时开头加0,输出十六进制时开头加0x或0X.不能删除由g或G转换的输出数的尾部0 |
0 | 在字符宽度内在数的前端添加0.如果转换说明符是d,i,o,u,x或X且指定了精度,可忽略标志0| |
/***************************************
* using_printf_4.c *
* *
* printf库函数的格式化字符串中的标志 *
***************************************/
#include <stdio.h>
int main()
{
int x1 = 128;
printf("x1(右对齐): %5d\n", x1);
printf("x1(左对齐): %-5d\n", x1);
printf("x1(显示'+'): %+5d\n", x1);
int x2 = -128;
printf("x2(负数+标志无效): %+5d\n", x2);
printf("x1(空格做前缀): % 5d\n", x1);
printf("x2(空格做前缀): % 5d\n", x2);
printf("x1(八进制开头+0): %#o\n", x1);
printf("x1(十六进制开头+0x): %#x\n", x1);
printf("x1(十六进制开头+0X): %#X\n", x1);
double x3 = 5.000;
printf("x3(g,不删除尾部0): %#g\n", x3);
printf("x3(G,不删除尾部0): %#G\n", x3);
printf("x1(0做前缀): %05d\n", x1);
return 0;
}
转换顺序
转换说明的解析顺序是由后向前的,首先根据<.p><L>X
将输入值按转换类型<L>X
转换为精度为p
的值,之后再经过<A><m>
进行最小字符宽度检测和处理。
/*******************************************
* using_printf_5.c *
* *
* 转换声明的解析顺序 *
*******************************************/
#include <stdio.h>
int main()
{
int x1 = 128;
printf("x1(1): %.6x\n", x1);
printf("x1(2): %#12.6x\n", x1);
char x2[] = "Hello World!";
printf("x2(1): %.5s\n", x2);
printf("x2(2): %12.5s\n", x2);
return 0;
}
转义序列
一些特殊字符(例如换行符)的输出需要依赖转义字符。转义序列是C语言为了处理字符集中的每一个字符而提供的特殊符号。转移序列分为两种,一种是字符型转义序列,一种是数字转义序列。C语言中包含的字符转义序列如下表:
名称 | 转义序列 |
---|---|
警报(响铃)符 | \a |
回退符 | \b |
换页符 | \f |
换行符 | \n |
回车符 | \r |
横向制表符 | \t |
纵向制表符 | \v |
反斜杠 | \\ |
问号 | \? |
单引号 | \' |
双引号 | \" |
字符转义序列只包含常用的字符,还有一些无法打印的ASCII字符及基本ASCII码字符以外的字符需要依赖数字转义序列。为了利用数字转义序列打印特殊字符,首先要查字符表获得该特殊字符的八进制或十六进制值,用八进制转义序列或十六进制转义序列表该特殊符号:
- 八进制转义序列。由字符
\
和跟随其后的不超过3位数字的八进制数组成。这里的八进制可以不用0开头。 - 十六进制转义序列。由字符
\x
和跟随其后的一个十六进制数组成。
参考文献
1.K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社
2. http://blog.csdn.net/patdz/article/details/8256843
3. http://www.goodxyx.com/c/article/cego30.html