一、printf()函数
1、函数原型
标准格式化输出函数:函数可以按用户指定的格式,把指定的数据显示到显示器屏幕上
int printf(const char *format, ...)
参数1 :format 是一个字符串,他的内容就是显示到屏幕终端的内容。其内容可以被后面的参数值替换,最终格式化输出到屏幕终端。
参数2 :… 表示的是变长参数,可以参数该函数若干个参数。
返回值 :返回的是一个整数。成功返回的是打印到屏幕上的字符数,但不包括 ‘\0’ ,出错返回的是一个负数。
2、类型符
注意:
(1)使用printf输出宽字符时,需要使用setlocale指定本地化信息并同时指明当前代码的编码方式。除了使用%S,还可以使用%ls。
(2)%a和%A是C99引入的格式化类型,采用十六进制p计数法输出浮点数。p计数法类似E科学计数法,但不同。数以0x开头,然后是16进制浮点数部分,接着是p后面是以 2为底的阶码。以上面输出的15.15为例,推算输出结果。15.15转换成二进制为1111.00 1001 1001 1001 1001 ...,因为二进制表示数值的离散特点,计算机对于小数有时是不能精确表示的,比如0.5可以精确表示为0.120.12,而0.15却不能精确表示。将15.15对应的二进制右移三位,为1.1110 0100 1100 1100 1100 ...转换对应的十六进制就是0x1.e4ccccccccccd,注意舍入时向高位进了1位。由于右移三位,所以二进制阶码就是3。最后的结果就是0x1.e4ccccccccccdp+3。
(3)格式控制字符串除了指明输出的数据类型,还可以包含一些其它的可选的格式说明,依序有 flags, width, .precision and length。
printf("%d", a); short int longprintf("%c", a); charprintf("%ld", a); longprintf("%lld", a); long longprintf("%f", a); float, double// printf("%lf", a); doubleprintf("%s", a); 字符串printf("%x", a); 十六进制printf("%X", a); 十六进制printf("%p", a); 十六进制printf("%o", a); 八进制, o不能大写printf("%e", a); 指数形式输出//printf("%i", a); 老式写法,现在都用dprintf("%u", a); 输出无符号数printf("%g", a); 输出浮点数,自动识别是指数形式还是小数形式
3、标志符
4、宽度和精度:
宽度 :如果要输出的数字长度大于指定宽度,则原样输出;如果要输出的数字长度小于指定宽度,则向左补空格。
精度:即要保留的小数位,如果要输出的小数位长度大于指定精度,则遵循四舍五入保留指定精度;如果要输出的小数长度小于指定精度,则会补0。
printf("%5d", a); 指定宽度,如果宽度不足,左补齐printf("%-5d", a); 指定宽度,如果宽度不足,右补齐printf("%-m.n", a); m为宽度,. 也算, 如果是-m 右补齐,正的左补齐putchar('c');puts("China");printf("%*s", 10, s); // *表示用后面的形参替代*的位置,实现动态格式输出/*意思是输出字符串s,但至少占10个位置,不足的在字符串s左边补空格,这里等同于printf("%10s", s);*/
5、转义字符
通俗来讲,转义字符就是加上\的字符和字符单独出现时所代表的意义不一样。
6、printf的缓冲区:
1、遇到\n
2、遇到 return
3、缓冲区已满(1024个字节)
4、强制刷新标准输出缓冲区(fflush(stdout));
翻译练习:
The arguments must correspond properly (after type promotion) with the conversion specifier.
正确对应 转换符
参数必须(在类型提升后)与转换说明符正确对应。
By default, the arguments are used in the order given,
默认情况下, 参数 按给定的顺序使用
where each '*' (see Field width and Preci‐sion below) and each conversion specifier asks for the next argument 要求
其中,每个“*”(请参阅下面的字段宽度和精度)和每个转换说明符都要求输入下一个参数
(and it is an error if insufficiently many arguments are given).
(如果给出的论据不够多,则是错误的)
One can also specify explicitly which argument is taken, at each place where an argument is required,
还可以明确指定在每个需要参数的地方使用哪个参数,
by writing "%m$" instead of '%' and "*m$" instead of '*',
通过写入“%m$”而不是“%”,以及写入“*m$”而不是“*”,
where the decimal integer m denotes the position in the argument list of the desired argument, indexed starting from 1.
其中,十进制整数m表示所需参数在参数列表中的位置,从1开始索引。
Thus,
因此
printf("%*d", width, num);
and
printf("%2$*1$d", width, num);
are equivalent.
是等效的。
The second style allows repeated references to the same argument.
第二种样式允许重复引用同一个参数。
The C99 standard does not include the style using '$', which comes from the Single UNIX Specification.
C99标准不包括使用来自单个UNIX规范的“$”的样式。
If the style using '$' is used, it must be used throughout for all conversions taking an argu‐ment and all width and precision arguments,
如果使用了使用“$”的样式,则必须在整个转换过程中使用该样式,该转换采用参数以及所有宽度和精度参数,
but it may be mixed with "%%" formats, which do not consume an argument.
但它可能与不使用参数的“%%”格式混合。
There may be no gaps in the numbers of arguments specified using '$';
使用“$”指定的参数数量可能没有差距;
for example, if arguments 1 and 3 are specified, argument 2 must also be specified somewhere in the
format string.
例如,如果指定了参数1和3,则还必须在格式化字符串。
二、scanf
getchar(c);
gets(str); --> C11中删除了gets(), 所以vs使用的是gets_s(str, 6); 注意输入不能大于6,因为有 \0
scanf("%d", &a);
//scanf("%i", &a);
scanf("%u", &a);
scanf("%o", &a);
scanf("%x", &a);
scanf("%c", &a);
scanf("%s", &a);
scanf("%f", &a);
scanf("%lf", &a); double 必须用这个,否则数据接收不全会出问题
scanf("%hd", &b); 输出short,如果用d 程序可能会崩
scanf("%d%*d",&a,&b); // 添加了*的部分会被忽略
// eg: 输入"123 456", 123给了a,b不会被赋值