【C基础】02 格式化输入/输出[scanf函数/printf函数]

本章补充内容见14 格式化输入输出补充

1、printf函数

1.1、格式:

printf ( 格式串,表达式1 , 表达式2 ) ;
格式串 = 转换说明 + 普通字符
转换说明的数量与输出项的数量需相等且一 一对应,包括变量类型的对应

	printf("%d %d", a,b);  //正确

	printf("%d %d", a);    //错误!
	printf("%d", a,b);     //错误!

1.2、转换说明(含格式化信息)

格式:
% m.p X
例如:%3d、`%3.4f

m —— 最小栏宽。指明要显示的最少字符数。数据实际位数大于m,则完整显示;小于则右对齐,左侧空格补齐。m为负则左对齐。对浮点型,m也包含小数位和小数点位。

  • 举例:
    原数据为1234,%3d输出为1234,%5d输出为·1234(右对齐,左侧用空格补全)

p —— 精度。 依赖于转换类型X

  • X是d(十进制整型)。p规定最小个数不足则数字左侧补零。无p,则默认为1。
  • X是e (指数,科学计数法)。p表示小数点后应该出现的数字个数,小数不足则后面补0,默认6位。p=0,则不显示小数点。
  • X是f(定点十进制)p表示小数点位数。
  • X是g(指数形式+定点十进制的浮点数)p表示指数的有效数字(不是小数点后的数字)的最大数量。不显示尾随的0,若无小数,则不显示小数点。

总结:m规定最小栏宽,p对浮点型规定最大小数位,对整型规定最小位数(与m略有不同)。

举例:

	int i;
	float x;
	i = 40;  x = 839.21f;	
	printf("|%d|\n",i);   //加“|”便于观察输出长度
	printf("|%5d|\n",i);
	printf("|%-5d|\n",i);
	printf("|%5.3d|\n",i);
	printf("|%10.3f|\n\n",x);
	printf("|%10.3e|\n",x);   //注意这个
	printf("|%-10g|\n",x);
	

输出结果为:
请添加图片描述

1.3、转义序列

1.3.1 符号转义序列

举例:

\n —— 换行
\a —— 响铃
\b —— 回退一位
\t —— 水平制表,将光标移到下一个制表符的位置。水平制表符的宽度由操作系统决定,通常为8个字符宽度
\" —— 表示字符“"”,“"”标记字符串的开始和结束
\\ —— 显示一个\

程序举例1:

	printf("Item\tUnit\cPurchuse\n\tPrice\tDate\n");
	printf("\"Hello\"");

输出结果为:
请添加图片描述

1.3.2 数字转义序列

符号转义序列可以使用相应的ASCII码(8进制或16进制)替换为数字转义序列来使用。例如:\n == \12 == \x0a == \x0A

详见ASCII码表。

二、scanf函数

1、格式:

scanf函数格式与printf函数相同。

示例:

	int i,j;
	float x,y;

	scanf("%d%d%f%f",&i,&j,&x,&y); //scanf函数转换说明紧挨着的情况很普遍,printf则少有

说明:

  1. 转换说明与变量的数量应相等且一一对应
  2. 变量类型也需对应
  3. &符号不可遗漏,否则可能产生“ format argument is not pointer ”的警告
  4. 使用scanf函数读取数据简单有效但不理想,可使用字符格式读取,再转换成数值形式。
  5. 函数传递指针时:
	int i, *p;      //定义指针变量
	p = &i;        //指针p存储i的地址
	scanf("%d", p);   //传入p,无需&符号

↑↓ 上下两段代码等价 ↑↓

	int i;
	scanf("%d", &i);

2、工作方法

(1)读取流程

  • 由转换说明寻找输入数据中适合类型的项,遇到不符合此项的字符时停止,并将其放回原处。
  • 寻找数的起始位置时,会忽略空白字符(包括空格符、水平/垂直制表符、换页符和换行符)

(2)识别规则

A.对整型:

  1. 先寻找正负号;
  2. 再寻找数字;
  3. 遇到非数字时停止。

B.对浮点型(%f、%e、%g同理):

  1. 寻找正负号;
  2. 寻找数字(可含小数点);
  3. 寻找指数(由字母e/E、可选符号和数字组成)。

举例:

针对输入数据1-20.3-4.0e3
调用语句为:

scanf("%d%d%f%f",&i,&j,&x,&y);

录入结果为:

i = 1;   j = -20;   x = 0.3;   y = -4000;

详细调用流程:

  • 转换说明%d。第一个非空的输入字符是1;因为整数可以以1开始,所以scanf函数接着读取下一个字符,即-。scanf函数识别出字符-不能出现在整数内,所以把1存入变量i中,而把字符-放回原处。
  • 转换说明%d。随后,scanf函数读取字符-、2、0和.(句点)。因为整数不能包含小数点,所以scanf函数把-20存入变量j中,而把字符.放回原处。
  • 转换说明%f。接下来scanf函数读取字符.、3和-。因为浮点数不能在数字后边有负号,所以scanf函数把0.3存入变量x中,而将字符-放回原处。
  • 转换说明%f。最后,scanf函数读取字符-、4、.、0、e、3和¤(换行符)。因为浮点数不能包含换行符,所以scanf函数把[插图]存入变量y中,而把换行符放回原处。
  • 此例中,scanf函数能够把格式串中的每个转换说明与一个输入项进行匹配。因为换行符没有读取,它将留给下一次scanf函数调用。

3、格式串中的普通字符

空白字符

  • scanf函数中格式串中的空白字符数量无关紧要,即
//以下两条语句等价
scanf("%d   %d      %f%f");
scanf("%d%d%f%f");
  • 格式串中的一个空白字符可以与输入中的任意数量的空白字符(包括0个)相匹配
   scanf("%d /%d",&num,&denum);   //读取分数,输入的分号"/"前后可以有任意数量的空格,同样匹配
   scanf("%d/%d",&num,&denum)//读取分数,输入的分号"/"前面不能紧邻空格,否则不匹配

其他字符(难点)

  • scanf函数格式串中遇到其他字符,将与输入字符比较,若匹配,则继续,不匹配则异常退出。

举例:

  • 若格式串为"%d/%d",输入为·5/·96(•表示空格),则匹配。
  • 若输入为·5·/·96,则格式串中的/与输入的第二个空格不匹配,此scanf函数异常退出。
  • %d /%d"(格式串相应位置有空格)与·5·/·96的输入匹配。

注意:scanf函数是以格式串为依据来检索输入数据,格式串中的空白字符直接被忽略。关键在于弄清先后顺序。

4、printf函数与scanf函数的区别

  • 两个函数都要调用数据;
  • scanf函数调用必须有&符号,printf函数不能有;
  • scanf函数寻找数据时通常会跳过空白字符,除转换说明外,格式串无需其他字符(含空白字符);
  • printf函数的格式串通常以\n结尾,scanf则不可,会导致程序出错;
  • scanf函数允许读入整个分数。

三、Q&A

  • %i%d的区别

对于printf函数而言,没有区别。对于scanf函数而言,%d只能读取十进制数,%i可读取八进制、十进制、十六进制。例如,%i056(有前缀0)为八进制数,视56为十进制数,视0x56(带前缀0x)为十六进制数。

  • 如何显示%符号?

在想要显示的几个%前多加一个%符号。

printf("%%");  //显示1个%
printf("%%%");  //显示2个%
  • 用户在两个数之间多输入“,”,scanf函数如何处理?

举例:

scanf("%d%d",&i,&j);

输入:4,28
结果:scanf函数将4存入i中之后返回。,28留待下一次scanf函数调用。

猜你喜欢

转载自blog.csdn.net/qq_43194080/article/details/122494471