文章目录
一、格式化输出函数printf
我们先来看一段熟悉的代码:
#include<stdio.h>
int main()
{
printf("Hello,world!\n");
return 0;
}
格式化输出函数:
这里就运用到了printf,“printf”表示打印的意思,“f”是“format(格式化)”的缩写,printf就是将指定数据格式化打印在屏幕上的函数。
1.占位符
那什么叫做格式化输出呢?
我们再来看一段代码:
int main()
{
printf("14+15=%d\n",14+15);
return 0;
}
输出结果如下:
14+15=29
上述代码的格式化输出,就是将“14+15”的值以整数形式输出,输出的位置即%d的位置,“%d”的就叫做占位符。
占位符:占位符的值是由printf函数逗号后面的数据决定的,同时占位符的类型又决定了数据的输出形式。
常见的占位符有如下几种:
- %d 或 %i:输出 int 类型的整数。
- %u:输出无符号整数。
- %f:输出浮点数。
- %s:输出字符串。
- %c:输出单个字符。
- %x 或 %X:以十六进制格式输出无符号整数。
- %p:输出指针地址。
- %%:输出 % 符号本身。
刚刚我们讲到,同时占位符的类型又决定了数据的输出形式。我们来看下面的代码:
printf("14+15=%d\n",14+15);
printf("%d\n",2.3);
输出结果如下:
14+15=29
1717986918
此处我们看到,第二段printf输出的并不是2.3,那是因为,%d要求的是输出int类型的数据,但是2.3是浮点类型的数据。此时printf就会从错误的内存中读取一个整形数据来作为结果输出。
正确的编写方式应当是:
printf("%f\n", 2.3);
2.返回值、换行符
- printf的返回值就是双引号内的文本内容
- 换行符:
我们可以看到,我们在使用printf函数的时候都会默认在文本的后面加上个换行符\n。
这是因为当我们输出一个printf函数后,此刻屏幕上的光标会停留在该函数文本的末尾,如果再输出一个printf函数,新的文本内容就会紧挨着前一个内容,造成编程员和读者的不易理解。
下面我们来看有无换行符的区别
- 有换行符:
printf("Hello,world!\n");
printf("14+15=%d\n", 14 + 15);
printf("%f\n", 2.3);
输出结果如下:
Hello,world!
14+15=29
2.300000
- 没有换行符:
Hello,world!14+15=292.300000//此时我们可以看到,输出的结果是不易理解的
当然,换行符也可以出现在文本的中间:
printf("Hello\nworld!\n");
输出结果如下:
Hello
world!
3.输出数据的最小宽度
对于这么一段数据:我们希望%d处的数据占到3个宽度。
#include<stdio.h>
int main()
{
printf("1+2=%3d\n",3);
return 0;
}
输出结果如下:
1+2=3
我们只需要在将"%d"修改成"%3d"即可。
printf("1+2=%3d\n",3);
printf("1+2=%3d\n",3);
输出结果如下:
1+2=3
1+2= 3
换个情况,假如是:
printf("1120+11=%3d\n",1131);
输出结果:
1120+11=1131
1131的长度显然已经超出的3个宽度,那为什么输出的是1131,而不是113呢。
%3d是决定了数据输出的最小宽度,若是不满足该宽度,就在其左端补足空格符,满足或大于该宽度,就正常输出该数据。
上述我们看到的情况是左对齐的形式补足空格符,如果要右对齐,就将限定宽度改为负数即可。
printf("11+7=%-6d,\n11+7=%6d。",18,18);
输出结果如下:
11+7= 18 ,//在18的后面补足4个空格
11+7= 18。//在18的前面补足4个空格
4.输出浮点数的最小小数位数
我们在输出浮点数的时候,默认打印的是小数点后6位数。那如果想要**限定小数位数呢?**
printf("%.3f",1.18);//.3代表输出到小数点后三位
printf("%.2f",1.18);//.2代表输出到小数点后两位
下面我们来看输出结果:
1.180
1.18
和最小宽度的规则一样,小于最小位数的向后补零,反之正常输出。
将最小宽度和最小位数的规则结合起来,我们可以限制浮点数的输出形式。
printf("%6.3f.\n", 1.18);
printf("%-6.3f.\n",1.18);
printf("%2.3f.\n", 1.18);
输出结果如下:
1.180.
1.180 .
1.180.
5.显示数据的正负号
在刚才的结果输出中,正数前面是不带有正号的。
那如果我们想要让其带有正号呢?
只需要在占位符的%后紧跟一个正号+即可:
printf("%+6.3f.\n", 1.18);
printf("%-6.3f.\n",-1.18);
printf("%+2.3f.\n", -1.18);
输出结果如下:
+1.180.
-1.180.
-1.180.
6.限制字符串的输出
对于"Hello,word!"这一个字符串,如果我们只想输出前面的“Hello”
我们可以:
printf("%.5s\n", "Hello, word!");//
此处%.5表示只输出五个字符
此时我们又想要限定输出的Hello的宽度:
printf("%.5s\n", "Hello, word!");
printf("%8.5s\n", "Hello, word!");
printf("%-8.5s\n", "Hello, word!");
输出结果如下:
Hello
Hello
Hello
二、格式化输入函数scanf
1.认识scanf
scanf的scan意为扫描、读取,f为format的缩写,scanf意为按照指定的格式读取输入的数据。
其返回值时读取成功的数据的个数。
当我们创建变量的时候,会对变量进行初始化,那么如果用户想要自己给变量赋值的时候,就会用到scanf函数。
下面我们来看一个加法运算:
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
printf("请输入两个整数:a,b\n");
scanf("%d,%d", &a, &b);
printf("答案是:%d\n", a + b);
return 0;
}
此处我们人为地对a,b赋值,并得到a+b的值
当程序运行到scanf处时,会停下来让用户输入值。按下回车键程序会继续运行
输出结果如下:
请输入两个整数:a,b
1 2
答案是:1
2.占位符
和printf一样,scanf也有占位符:
- %d:读取一个十进制整数。
- %i:读取一个整数(自动检测十进制、八进制或十六进制)。
- %f:读取一个浮点数(float类型)。
- %lf:读取一个双精度浮点数(double类型)。
- %c:读取一个字符。
- %s:读取一个字符串,直到遇到空白字符(如空格、制表符或换行符)。
不同的是,每个占位符与之对应的变量的地址,占位符代表的类型要和变量的类型相一致。
如下,&是取地址符,是将变量a和变量b的地址取出。
scanf("%d,%d", &a, &b);
要注意的是,我们输入数据的格式应当和形参(%d,%d)的表达形式一样,有逗号逗号就不能省略。
当我们输入字符串的时候要注意:scanf读取字符串是从第一个空白字符开始读取,直到遇到新的空白字符结束。
int main()
{
char str[100] = {};//此处是声明了一个长度为100的数组
printf("请一段字符串:\n");
scanf("%s", &str);
printf("%s\n",str);
return 0;
}
如果我们输入的是:
abcd ef
那么输出的结果是:
abcd
3.赋值忽略符
每个用户输入数据时所加的字符是不同的,有逗号或者空格等。
当然,我们也可以用赋值忽略符解决这一问题:
int a = 0;
int b = 0;
printf("请输入语文和数学成绩:\n");
scanf("%d%*c%d", &a, &b);
printf("语文:%d,数学:%d\n", a , b);
return 0;
赋值忽略符*,放在%的后面,是将该位置的字符消除对应的变量,所以无论用户输入的时100,98还是100;98,对结果都没有影响。
- 除此之外,我们也可以屏幕上打印数据的输出格式,来方便输入。
4.使用注意
1.当使用 %s 读取字符串时,scanf 不会检查数组的边界,所以可能会发生缓冲区溢出。建议使用更安全的函数,如 fgets。
2.使用 scanf 需要小心处理留在输入缓冲区中的字符,特别是换行符,它可能会影响后续的输入操作。
3.为了避免输入格式错误,可以在 %s 前添加宽度限制,如 scanf(“%49s”, name);,这样可以防止用户输入超过数组边界的字符数。
5.VS系统上使用scanf的问题
在VS上使用scanf时系统运行时会报错:
我们看到错误列表显示:
提示说:
我们可以将scanf换成scanf_s:
或者在代码开头加上:#define _CRT_SECURE_NO_WARNINGS 1: