C

C 知识量:16 - 74 - 317

4.3 printf()函数><

printf()函数- 4.3.1 -

printf()函数是C语言的输入函数,在使用时要注意请求打印的数据要与待打印的数据类型相匹配。例如,如果要打印int类型的数据,就要使用%d;如果要打印字符类型的数据,就要使用%c。“%d”和“%c”这类符号称为转换说明,它们用于说明如何把数据转化成可显示的形式。

ANSI C标准提供的转换说明如下:

转换说明
输出
%a 浮点数、十六进制数和p记数法(C99/C11)
%A 浮点数、十六进制数和p记数法(C99/C11)
%c 单个字符
%d 有符号十进制整数
%e 浮点数,e记数法
%E 浮点数,e记数法
%f 浮点数,十进制记数法
%g 根据值的不同,自动选择%f或%e。%e格式用于指数小于-4或者大于或等于精度时
%G 根据值的不同,自动选择%f或%E。%E格式用于指数小于-4或者大于或等于精度时
%i 有符号十进制整数(与%d相同)
%o 无符号八进制整数
%p 指针
%s 字符串
%u 无符号十进制整数
%x 无符号十六进制整数,使用十六进制整数0f
%X
无符号十六进制整数,使用十六进制整数0F
%% 打印一个百分号

使用printf()- 4.3.2 -

以下是一个使用printf()函数及转换说明的示例:

#include <stdio.h>
#include <string.h>

int main(void) {
	/*printf()函数及转换说明示例*/
	int a = 23;
	float b = 6.5;
	char c = '@';
	printf("The result of %d*%f is %c %f.", a, b, c, a*b);
	system("pause");
	return 0;
}

运行的结果为:

The result of 23*6.500000 is @ 149.500000.

printf()函数的格式为:printf(格式字符串,待打印项1,待打印项2,...)。其中,待打印项1,待打印项2等都是要打印的项,可以是变量、常量或者表达式。而格式字符串是由双引号括起来的内容,其中就包含了转换说明。

特别需要注意的是:转换说明不论从数量上、次序上、还是格式上都必须与后面的待打印项匹配,否则就要出错。例如,在以上示例中,按顺序从左到右,%d、%f、%c、%f依次对应后面的a、b、c和a*b(即a乘以b的积)。a乘以b的积被作为一个结果打印出来说明printf()函数使用的是值,无论是变量、常量还是表达式的值。

转换说明修饰符- 4.3.3 -

使用printf()函数时,在%和转换字符之间插入修饰符可以修饰基本的转换说明。

printf()函数的修饰符如下:

修饰符含义
标记
有5种标记(-、+、空格、#、0),可以不使用或同时使用多个标记。例如:%-12d
数字
表示最小字段宽度,如果设置的字段对于值来说太小,系统会使用更宽的字段。例如:%2d
.数字

表示精度。

  • 对于%e、%E和%f转换,表示小数点右边数字的位数。

  • 对于%g和%G转换,表示有效数字最大位数。

  • 对于%s转换,表示待打印字符的最大数量。

  • 对于整型转换,表示待打印数字的最小位数。

  • 如有必要,使用前导0来达到这个位数。

  • 只使用.表示其后跟随一个0,所以%.f和%.0f相同。

例如:%6.4f表示打印一个浮点数,字段宽度为6个字符,小数点后面有4位。

h和整型转换说明一起使用,表示short int或unsigned short int类型的值。例如:%hu
hh和整型转换说明一起使用,表示signed char或unsigned char类型的值。例如:%hhu
j和整型转换说明一起使用,表示intmax_t或uintmax_t类型的值,这些类型定义在stdint.h中。例如:%jd
l和整型转换说明一起使用,表示long int或unsigned long int类型的值。例如:%ld
ll和整型转换说明一起使用,表示long long int或unsigned long long int类型的值。例如:%lld
L和浮点转换说明一起使用,表示long double类型的值。例如:%Ld
t和整型转换说明一起使用,表示ptrdiff_t类型的值,ptrdiff_t是两个指针差值的类型。例如:%td
z
和整型转换说明一起使用,表示size_t类型的值,size_t是sizeof返回的类型。例如:%zd

在C语言中没有用于float类型的修饰符,因为printf()函数中所有的float类型的参数会自动转换成double类型。

printf()函数的5种标记如下:

标记含义
-待打印项左对齐,也就是从字段左侧开始打印。例如:%-12s
+有符号值如果为正,则在值前面显示加号;如果为负,则显示减号。例如:%+5.2f
空格有符号值如果为正,则在值前面显示前导空格(不显示任何符号);如果为负,则显示减号。其中,+标记会覆盖一个空格。例如:% 5.2f
#把结果转换为另一种形式。如果是%o,则以0开始;如果是%x或%X,则以0x或0X开始。对于所有浮点格式,#保证了即使后面没有任何数字,也打印一个小数点字符。对于%g和%G,#防止结果后面的0被删除。例如:%#7.0f
0对于数值格式,用前导0代替空格填充字段宽度。对于整数格式,如果出现-标记或指定精度,则忽略该标记。

以下是一个应用修饰符的示例:

#include <stdio.h>
#define ME "I love China!"
int main(void) {
	/*printf()函数修饰符应用*/
	const int number1 = 911;
	const double number2 = 365.32;
	printf("***part one:911***\n");
	printf("@%d@\n", number1);
	printf("@%2d@\n", number1);
	printf("@%10d@\n", number1);
	printf("@%-10d@\n", number1);
	printf("***part two:365.32***\n");
	printf("@%f@\n", number2);
	printf("@%e@\n", number2);
	printf("@%3.2f@\n", number2);
	printf("@%10.3f@\n", number2);
	printf("@%10.3E@\n", number2);
	printf("@%+3.1f@\n", number2);
	printf("@%010.2f@\n", number2);
	printf("***part three***\n");
	printf("%x %X %#x\n",55,55,55);
	printf("@@%d@@% d@@% d@@\n",23,23,-23);
	printf("@@%6d@@%6.2d@@%06d@@%06.2d@@\n",1,1,1,1);
	printf("***part four***\n");
	printf("[%2s]\n",ME);
	printf("[%22s]\n",ME);
	printf("[%22.6s]\n",ME);
	printf("[%-22.6s]\n",ME);
	system("pause");
	return 0;
}

运行结果为(对应部分为添加的解释内容):

***part one:911***
@911@                                 对应:@%d@
@911@                                 对应:@%2d@
@       911@                          对应:@%10d@
@911       @                          对应:@%-10d@
***part two:365.32***
@365.320000@                          对应:@%f@
@3.653200e+002@                       对应:@%e@
@365.32@                              对应:@%3.2f@
@   365.320@                          对应:@%10.3f@
@3.653E+002@                          对应:@%10.3E@
@+365.3@                              对应:@%+3.1f@
@0000365.32@                          对应:@%010.2f@
***part three***
37 37 0x37                            对应:%x %X %#x
@@23@@ 23@@-23@@                      对应:@@%d@@% d@@% d@@
@@     1@@    01@@000001@@    01@@    对应:@@%6d@@%6.2d@@%06d@@%06.2d@@
***part four***
[I love China!]                       对应:[%2s]
[         I love China!]              对应:[%22s]
[                I love]              对应:[%22.6s]
[I love                ]              对应:[%-22.6s]

以上代码中使用了const关键字,限定了变量为只读。

转换说明的意义- 4.3.4 -

转换说明就是告诉计算机将二进制格式存储的值转换成一系列的字符(或字符串)以便于显示,其实本质上就是一个翻译说明。例如:%d表示:把给定的值(计算机中的二进制数据)翻译成十进制整数文本并打印出来。

下面是一个错误使用转换说明的示例:

#include <stdio.h>

int main(void) {
    /*错误的转换说明*/
    float n1 = 6.51;
    double n2 = 3.1546;
    long n3 = 60000;
    long n4 = 9876543210;
    printf("n3=%ld,n4=%ld\n", n3, n4);
    printf("n1=%ld,n2=%ld,n3=%ld,n4=%ld", n1, n2, n3, n4);
    system("pause");
    return 0;
}

运行结果为:

n3=60000,n4=1286608618
n1=-2147483648,n2=1075448381,n3=-322981541,n4=1074347166

在第一个printf()函数中n3,n4都使用了正确的转换说明,但是n4的值超出了long类型的取值范围,因此打印出错。在第二个printf()函数中,n1,n2使用了错误的转换说明,因此打印出错。在程序中通常把传入的值放入被称为栈的内存区域中,因此,n1,n2,n3,n4是存储在连续的内存区域中,使用错误的转换说明导致程序错误的读取了n1,n2的内存区域,当读取到n3,n4时,读取操作在栈中的起始位置已经出错,也就不可能正确的读取n3和n4的值了。

printf()函数的返回值- 4.3.5 -

printf()函数的返回值是其打印字符的个数。但如果有输出错误,则会返回一个负值。

#include <stdio.h>

int main(void) {
    /*printf()函数的返回值*/
    int number = 12345678;
    int remember = 0;
    remember = printf("%d", number);
    printf("\nremember is : %d",remember);
    system("pause");
    return 0;
}

运行结果:

12345678
remember is : 8

注意:printf()函数返回值的计数包含空格和不可见的换行符(\n),因此,为了分行表示打印内容,以上程序中在第二个printf()函数开头使用了换行符(\n)。

打印较长的字符串- 4.3.6 -

如果要打印较长的字符串,可以使用以下分隔方法:

#include <stdio.h>

int main(void) {
    /*printf()打印较长的字符串*/
    /*第一种方法*/
    printf("Good morning. I am glad to");
    printf(" be here for this interview.\n");
    /*第二种方法*/
    printf("Good morning. I am glad to\
 be here for this interview.\n");
    /*第三种方法*/
    printf("Good morning. I am glad to"
            " be here for this interview.\n");
    system("pause");
    return 0;
}

运行结果:

Good morning. I am glad to be here for this interview.
Good morning. I am glad to be here for this interview.
Good morning. I am glad to be here for this interview.

特别要注意第二种方法,反斜杠后面内容另起一行后前面不要有空格,否则空格也会打印出来。(示例中根据需要特意留了一个空格)