int printf(const char * format, ... );
很显然,与其他库函数不同的是,printf 函数是一个“可变参数函数”(即函数参数的个数是可变的)。确切地说,是其输出参数的个数是可变的,且每一个输出参数的输出格式都有对应的格式说明符与之对应,从格式串的左端第 1 个格式说明符对应第 1 个输出参数,第 2 个格式说明符对应第 2 个输出参数,第 3 个格式说明符对应第 3 个输出参数,以此类推。其中,格式说明符的一般形式如下(方括号 [] 中的项为可选项):
%[flags][width][.prec][length] type_char
/*用中文标识如下:*/
%[标志符][宽度][精度][长度]类型符
符 号 | 类 型 | 说 明 | 示 例 | 结 果 |
---|---|---|---|---|
% | 无 | 输出字符“%”本身 | pnntf("%%"); | % |
d、i | int | 以整型输出 | printf("%i,%d", 100,100); | 100,100 |
u | unsigned int | 以无符号整型输出 | printf( "%u,%u",100u,100); | 100,100 |
o | unsigned int | 以八进制无符号整S输出 | printf( "%o”,100); | 144 |
x | unsigned int | 以十六进制小写输出 | printf("%x",11); | b |
X | unsigned int | 以十六制大写输出 | printf("%X",11); | B |
int main(void) { int pos=0; int x = 123; int y = 456; printf("%d%n%d\n", x, &pos, y); printf("pos=%d\n", pos); return 0; }很显然,上面代码中的 pos 将输出 3,即“123”的长度,运行结果为:
int main(void) { char buf[20]; int pos=0; int x = 0; snprintf(buf, sizeof(buf), "%.100d%n", x, &pos); printf("pos=%d\n", pos); return 0; }很显然,上面的代码会输出 100,而不是 20。
char daddr[16]; int main(void) { char buf[100]; int x=1; memset(daddr,'/0',16); printf("前X: %d/%#x (%p)\n", x, x, &x); strncpy(daddr,"AAAAAAA%n",9); snprintf(buf,sizeof(buf),daddr); buf[sizeof(buf) - 1] = 0; printf("后X: %d/%#x (%p)\n",x, x, &x); return 0; }在上面的代码中,x 将被从 1 修改成 7,其运行结果为:
符号 | 说 明 |
---|---|
(空白) | 右对齐,左边填充 0 和空格 |
(空格) | 输出值为正时加上空格,为负时加上负号 |
- | 输出结果为左对齐(默认为右对齐),边填空格(如果存在表格最后一行介绍的0,那么将忽略0) |
+ | 在数字前增加符号“+”(正号)或“-”(负号) |
# | 类塑符是o、x、X吋,增加前缀0、0x、0X;类型符是e、E、f、F、g、G时,一定要使用小数点;类型符是g、G时,尾部的 0 保留 |
0 | 参数的前面用0填充,直到占满指定列宽为止(如果同时存在“-”,将被“-”覆盖,导致 0 被忽略 |
符号 | 说 明 |
---|---|
n | 至少输出 n 个字符(n 是一个正整数)。如果输出少于 n 个字符,则用空格填满余下的位置(如果标识符为“-”,则在右侧填,否则在左端填) |
0n | 至少输出 n 个字符(n 是一个正整数)。如果输出值少于 n 个字符,则在左侧填满 0 |
* | 输出字符个数由下一个输出参数指定(其必须为一个整形量) |
符号 | 说 明 |
---|---|
无 | 系统默认精度 |
.0 | 对于 d、i、o、u、x、X等整形类型符,采用系统默认精度;对于f、F、e、E等浮点类型符,不输出小数部分 |
.n |
1) 对于d、i、o、u、x、X类型符,至少输出 n 位数字,且:
3) 对于 g 和 G 类型符,最多输出 n 位有效数字 4) 对于 s 类型符,如果对应的输出串的长度不超过 n 个字符,则将其原样输出,否则输出其头 n 个宁符 |
* | 输出精度由下一个输出参数指定(其必须为一个整型量) |
符号 | 说 明 |
---|---|
hh | 与d、i 一起使用,表示一个signed char 类型的值;与o、u、x、X—起使用,表示一个unsigned char 类型的值;与 n 一起使用,表示相应的变元是指向 signed char 型变量的指针(c99 ) |
h | 与d、i、o、u、x、X 或 n 一起使用,表示一个short int 或 unsigned short int 类型的值 |
l | 与d、i、o、u、x、X 或 n 一起使用,表示一个 long int 或者 unsigned long int 类型的值 |
ll | 与 d、i、o、u、x、X 或 n —起使用,表示相应的变元是 long long int 或 unsigned long long int 类型的值(c99 ) |
j | 与 d、i、o、u、x、X 或 n —起使用,表示匹配的变元是 intmax_t 或 uintmax_t 类型,这些类型在“stdint. h”中声明(c99 ) |
z | 与 d、i、o、u、x、X 或 n —起使用,表示匹配的变元是指向 size_t 类型对象的指针,该类型在“stddef. h”中声明(c99 ) |
t | 与d、i、o、u、x、X 或 n —起使用,表示匹配的变元是指向 ptrdiff_t 类型对象的指针,该类型在“stddef. h”中声明(c99 ) |
L | 和a、A、e、E、f、F、g、G—起使用,表示一个long double类型的值 |
int k=8; printf("%d,%d\n",k,++k);对于上面的代码,表面上看起来输出的结果应该是“8,9”。但实际情况并非如此,在调用printf函数时,其参数是从右至左进行处理的,即将先进行 ++k 运算,所以最后的结果是“9,9”。由此可见,千万不要在 printf 语句中试图改变输出变量的值,如果确实需要改变,可以按照下面的示例代码形式来处理:
printf("%d\n",k); printf("%d\n",++k);这样处理之后,其结果就是我们所需要的“8,9”了。
int scanf (const char *format, ...);从函数原型可以看出,同 printf 函数相似,scanf 函数也是一个“可变参数函数”。同时,scanf 函数的第一个参数 format 也必须是一个格式化串。除此格式化串之外,scanf 函数还可以有若干个输入地址,且对于每一个输入地址,在格式串中都必须有一个格式说明符与之一一对应。即从格式串的左端第 1 个格式说明符对应第 1 个输入地址,第 2 个格式说明符对应第 2 个输入地址,第 3 个格式说明符对应第 3 个输入地址,以此类推。
%[*][width][length] type_char
/*用中文标识如下:*/
%[*][宽度][长度]类型符
int main(void) { char c[5]; int i=0; printf("输入数据(hello):\n"); for(i = 0;i < 5; ++i) { scanf("%c", &c[i]); } printf("输出数据:\n"); printf("%s\n", c); return 0; }对于上面这段示例代码,我们希望在“c[5]”字符数组中能够存储“hello”字符串,并在最后输出到屏幕上。从表面上看,这段程序没有任何问题,但实际情况并非如此。当我们依次输入“h(回车)”“e(回车)”,然后再输入“l”时,问题发生了。此时,程序不仅中断输入操作,而且会打印出字符数组 c 中的内容,其运行结果为:
#include <stdio.h> void flush() { char c; while ((c=getchar()) != '\n'&&c!=EOF); } int main(void) { char c[5]; int i=0; printf("输入数据(hello):\n"); for(i = 0; i < 5; ++i) { scanf("%c", &c[i]); flush(); } printf("输出数据:\n"); printf("%s\n", c); return 0; }这样,就从根本上解决了输入缓冲区问题,其运行结果为:
int main(void) { int a=0; printf("输入数据:\n"); /*请注意,这里多了一个回车符\n*/ scanf("%d\n",&a); printf("输出数据:\n",a); printf("%d\n",a); return 0; }在上面的代码中,因为在“scanf("%d\n",&a);”语句中多加了一个回车符“\n”,导致的结果就是要输入两个数,程序才会正常结束,而不是我们所期望的一个数。运行结果为:
Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有