printf 和 scanf

本文详细解析了printf和scanf函数的使用方法,包括各种格式化选项及其作用,帮助读者掌握如何精确控制数据的输入输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

int printf(const char *format, ...);

format包含:

    -- ordinary char

    -- conversion specification

conversion specification形式如下:

 %【flags】【width】【.precision】【h/l/L】conversion_char

【有效的flags,可以以任意顺序出现】
-(减号)在自己的输出域中左对齐,默认右对齐,输出域宽度由width指定。
+(加号)用于数字输出,总是显示数字的正负号。
space(空格)用于数字输出,如果数字前面没有正负号,就加一个空格以代替。
0(零)用于数字输出,用'0'补齐输出域。默认左对齐,当然0会补在数字前面,如果用-指定zuo对齐,0不会随便补在数字后面的哦^_^
#(井号)用于%o,输出前导'0';
用于%x,对于非零值,输出前导'0x';
用于%e,E,f,g,G,输出小数点;
用于%g,G,保留末尾的‘0’。

【width】的说明
widthThe converted argument will be printed in a field
at least [width] wide, and wider if necessary.
如果输出的字符宽度比width指定的小,那么用空格
补齐the field(在输出字符的左边或者右边,由flags决定),
如果输出的是数字并且flags指定了'0',那么用0补齐。

【.precision】的说明
-- 用于字符串,指定最大输出字符数;
-- 用于%e,E,f,指定小数点后保留位数;
-- 用于%g,G,指定有效数字位数;
-- 用于整数,指定最小输出的digit数,包含八进制的前导0,不包含十六进制的前导0x,不足的话用0补齐。

【h/l/L】的说明
h指定对应的arg是signed short 或者unsigned short
l(ell)指定对应的arg是signed long 或者unsigned long
L指定对应的arg是long double

说明:对于width和precision,可以用一个'*'代替,那么此时width和precision的值是args中的对应的一个int类型arg的值。


【conversion_char】
d/iint输出格式为十进制有符号整数
ounsigned int八进制无符号整数(默认无前导0)
x/Xunsigned int十六进制无符号整数(默认无前导0x)
uunsigned int十进制无符号整数
schar *连续输出字符,遇到'\0'结束,或者输出个数满足precision指定的个数时也结束
fdouble十进制,格式为[-]mmm.ddd,ddd个数由precision指定,默认为6,0输出小数点
e/Edouble十进制,[-]m.ddde/E +/- xx,d的个数由precision指定,默认6,0强制输出小数点
g/Gdouble指数 < -4 or 指数 >= precision用%e/E,否则用%f;尾0和尾小数点都不会输出
pvoid *输出地址值,输出格式跟系统实现有关
nint *将当前输出的字符个数输入到对应的arg指向的int对象中
cint将对应的int类型arg转化成unsigned char,然后输出ascii表中对应的一个字符
% %%直接输出一个%

int scanf(const char *format, ...);

format中可以包含:

    -- 空白字符(转换时被忽略)

    -- 普通字符(除%外),要求完全匹配

    -- 转换序列(conversion specification),形式如下:

%【*】【width】【h/l/L】conversion_char

【*】
*与这个转换序列匹配的输入,将被跳过,scanf返回值也不会增加。

[cpp]  view plain copy
  1. int n, cnt;  
  2. cnt = scanf("%*d %d", &n);  
  3. /* 如果输入1  2,那么1被跳过,n的值为2,cnt的值为1 */  

【width】
指定输入域的最大宽度,以字符为单位,如1234  5678默认是两个输入域,如果指定%2d,那么只匹配12,3将作为下一次输入的开始。如果不指定width,输入域以空白字符为间隔。
[cpp]  view plain copy
  1. int m,n;  
  2. int cnt;  
  3. cnt = scanf("%2d %d", &m, &n);  
  4. /* 输入1234  56,m的值是12,n的值是34 */  

【h/l/L】
h用于%d i n o u x,说明对应的arg是short pointer
l(letter ell)用于%d i n o u x,说明对应的arg是long pointer;用于%e f g说明对应arg是double pointer
L用于%e f g,说明对应arg是long double pointer

【conversion_char】
dint *输入十进制整数
iint *输入整数,八、十或者十六进制
ounsigned int *输入八进制整数,leading 0 可有可无
uunsigned int *输入十进制整数
xunsigned int *输入十六进制整数,leading 0x可有可无
cchar *一个字符,当然这个字符不能使空白字符;
如果要读取紧接着的下一个字符,不管是否空白,应该用%1s
schar *对应输入域是一个字符串,arg指向的空间需要足够大,或者用%4s忽略可
能造成溢出的过多的输入
e/f/gfloat *【+/-】m【.ddd】【e/E】【+/- exp】
最好用1.0代替1,代替1. ,用0.1代替.1
pvoid *按照printf("%p")输出的格式输入一个有效地址
nint *功能同printf("%n"),特殊
[...]char *%[abc]s,如果输入a12bc,那么从输入域的a开始,如果a在[abc]里,
接着确定1是否在[abc]里,如果不在,%[abc]s这个conversion specification
匹配完成,scanf函数返回![]...]包含']'
[^...]char *与上匹配过程相反[^]...]包含']'
% 要求输入一个%
注意:scanf返回值是已经匹配成功,并且发生赋值的number。如%n虽然发生赋值,但是没有匹配输入,所以不会使返回值增加;scanf("abcd%%")输入abcd%能完全匹配,但是不会发生赋值,也不会使返回值增加。

谨记:

考虑用户输入的多样性;

代码中conversion specification和...严格匹配;

要求conversion specification序列中各个元素之间的组合有效有意义;

不耍花样,不钻牛角尖。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值