一、printf()
printf()的返回值为输出的字符个数:
例:rv = printf (“hello”); 结果为rv = 5;
其格式控制如下列表所述:
表一、printf()格式转换说明符
注意:不要忘记给控制字符串后面的列表中的每个项目都使用一个转换说明。
转换说明 输出
%a 浮点数、十六进制数和p-记数法(C99)
%A 浮点数、十六进制数和p-记数法(C99)
%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()格式转换修饰符
修饰 意义
标志
五种标志(-、+、空格、#、0)详细说明见表三。可以使用零个或者多个
例:“%-10d”
digit 或*
字段宽度的最小值。如果该字段不能容纳要打印的数或者字符串,系统就会使用更宽的字段。当为 * 号时,表示从参数中获取宽度。
例:“%4d”、printf(“%*d”, width, num)
.digit或 .*
精度。对于%e、%E和%f转换,是将要在小数点的右边打印的数字的位数。对于%g和%G转换,是有效数字的最大位数。对于%s转换,是将要打印的字符的最大数目。对于整数转换,是将要打印的数字的最小位数,如果必要,要使用前导0来达到这个位数。只使用“.“和使用“.0”相同,所以%f与%.0f相同。当为 * 号时,表示从参数中获取精度。
例:“%5.2f“、printf(”%5.*f", precision, num)
h
和整数转换说明符一起使用,表示一个short int 或 unsigned short int类型数值
例:”%hu“、”%hx“、”%6.4hd“
hh
和整数转换说明符一起使用,表示一个char 或 unsigned char类型数值
例:”%hhu“、”%hhx“、”%6.4hhd“
j
和整数转换说明符一起使用,表示一个intmax_t或uintmax_t值
例:”%jd“、”%8jx“
l
和整数转换说明符一起使用,表示一个long nt 或 unsigned long int类型数值
例:”%ld“、”%8lu“
ll
和整数转换说明符一起使用,表示一个long long int 或 unsigned long long int类型数值(C99)
例:”%lld“、”%llu“
L
和浮点转换说明符一起使用,表示一个long double值
例:”%Lf“、”%10.4Le“
t
和整数转换说明符一起使用,表示一个ptrdiff_t值(与两个指针之间的差相对应的类型)(C99)
例:”%td“、”%12ti“
z
和整数转换说明符一起使用,表示一个size_t值(C99)
例:“%zd”、“%12zx”
表三、printf()格式转换修饰标志
标志 意义
项目是左对齐的
例:“%-4s”
有符号的值若为正,则显示正号;若为负的,则显示负号
例:“%+6.2f”
空格
有符号的值若为正,则显示空格代替正号;若为负的,则显示负号
例:“% 6.2f“
使用转换说明的可选形式。若为%o格式,显示前导0;若为%x和%X格式,则显示前导0x和0X。对于所有浮点形式,#保证了即使不跟任何数字,也打印一个小数点字符。对于%g和%G格式,它防止尾随零被删除。
例:”%#o“、”%#x“、”%#8.0f“、”%+#10.3E“
0
对于所有的数字格式,用前导0来填充字段宽度,如果出现-标志或者指定了精度(对于整数)则忽略该标志
例:”%010d“、”%08.3f“
关于字段宽度扩展:
printf可在字段宽度部分使用*代替数字来达到目的,但是也必须使用一个参数来说明函数字段宽度应该是什么。
例如:
int width = 8;
printf (“%*d”, width, number);
二、scanf()
scanf() 开始读取输入以后,会在遇到的第一个空白制度空格(bank)、制表符(tab)或者换行符(newline)处停止读取。
scanf()的返回值为成功输入的项目个数,其控制格式如下列表所述
表四、scanf()格式转换说明符
转换说明符
意义
%c 把输入解释成一个字符
%d 把输入解释成一个有符号十进制整数
%e、%f、
%g、%a
把输入解释成一个浮点数(%a是C99标准)
%E、%F、
%G、%A 把输入解释成一个浮点数(%A是C99标准)
%i 把输入解释成一个有符号十进制整数
%o 把输入解释成一个有符号八进制整数
%p 把输入解释成一个指针(一个地址)
%s 把输入解释成一个字符串:输入的内容以第一个非空白字符作为开始,
至下一个空白字符之前的全部字符
%u 把输入解释成一个无符号十进制整数
%x、%X
把输入解释成一个无符号十六进制整数
表五、scanf()格式转换修饰符
修饰符 意义
*
忽略一个输入项
例:scanf(“%*d%d”, &num), 当输入为 23 45时,23将被忽略,而读取45到num中
digit 最大字段宽度。在达到最大字段宽度或遇到第一个空白字符时停止对输入项的读取
hh 指示整数将会存储在char 或 unsigned char
ll 指示整数将会存储在 long long 或者 unsigned long long (C99)
h、l、L
”%hd“和”%hi“指示该值将会存储在一个short int中。”%ho“、”%hx“”%hu“指示该值将会存储在一个unsigned short int中。”%ld“和”%li“指示该值将存储在一个long中。”%lo“、”lx“、”lu“指示该值将会存储在一个unsigned long中。”%le“、”%lf“、”%lg“指示该值将会存储在double中。将L与e、f、g一起使用指示该值将会存储在long double中。如果没有这些修饰符,d、i、o、x指示int类型,e、f、g指示float类型
空格 只能修饰 %c , 忽略输入的前导空白字符
对于scanf()除了%c以外,对每一个输入项忽略其前导空白字符(空格、制表艝、换行符)。从第一个非空白字符开始,直到遇到空白字符或达到宽度或遇到当前输入格式的非法字符时停止当前项输入,进入下一输入项
扩展:
1、当把*放在%和说明符字符之间时,它使函数跳过相应的输入项目。
例如:scanf (“%*d %*d %d”, &n);
输入: 12 34 56
则会跳过前两个整数,并把第三个整数复制个n
则输出结果为: 56
2、巧用scanf()返回值
status = scanf (“%ld”, &num);
while (status == 1){
status = scanf (“%ld”, &num);
} /当输入整数则执行while循环,例如输入Q,则scanf返回值为0,循环终止/
也可用下列形式代替:
while(scanf (“%ld”, &num) == 1) {}
3、变量参数的前面必须加上 “&” 符号。使用所有格式 (除了 %c 之外)时,输入值之前的空白(空格、制表符、换行符等)会被跳过,值后面的空白表示该值的结束。因此,用%s 格式码输入字符串时,中间不能包含空白。
4、再论printf() 函数
声明:
int printf(const char *format, …)
参数:
format – 这是字符串,包含了要被写入到标准输出 stdout 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。
#include <stdio.h>
int main(void)
{
char *s = “11111\n”;
printf (“%s”, s); //用的是字符串里面的换行符
printf (s); //s 为字符串
return 0;
}
编译出现警告: 警告: 格式字符串不是一个字面字符串而且没有待格式化的实参 [-Wformat-security]
输出结果:
11111
11111
5、斜杠:“/” 与 反斜杠:“”
printf(“%d%d%d\n”, x,y,\
z)
注意这里是反斜杠:“”
简单总结:
数据类型和占位符之间的对应关系
char和unsingned char %c
short %hd
unsigned short %hu
long %ld
unsigned long %lu
int %d
unsigned int %u
float %f/%g
double %lf/%lg
%f和%lf会保留小数点后面多余的0 如 3.1400000 .2%f得 3.14
%g和%lg不会保留 如 3.14
%02d 两位数,如果不够前面补0, 如 02