一、printf
1.基本用法
•printf
的作⽤是将参数⽂本输出到屏幕
•printf
= print
+ f
,printf
代表输出打印,f
代表 format
(格式化),format
表⽰可以定制输出⽂本的格式,所以详细来说printf
是将数据按照指定格式打印
•printf
是在标准库的头⽂件 stdio.h
定义的。使⽤这个函数之前,必须在源码⽂件头部引⼊这个头⽂件,否者编译器会报错
•加上去就不会了
•屏幕上打印 I LOVE C
•printf
不会在⾏尾⾃动添加换⾏符,运⾏结束后,光标就停留在输出结束的地⽅,不会⾃动换⾏
•如果想要换行打印
,可以在输出⽂本的结尾,添加⼀个换⾏符 \n
•没换行打印
•换行打印
•还可以在数据中换行(想在哪里换就哪里换)
2.占位符
•printf
可以在输出⽂本中指定占位符, “占位符”指的是这个位置可以⽤其他值代⼊
•比如我们打印 I have 5 pears
•上⾯⽰例中,I have %d pears
是输出⽂本,⾥⾯的 %d
就是占位符,表⽰这个位置要⽤其他值来替换。
•占位符的第⼀个字符⼀律为百分号%
,第⼆个字符表⽰占位符的类型,%d
表⽰这⾥代⼊的值必须是⼀个整数。
•printf
的第⼆个参数就是替换占位符的值,上⾯的例⼦是整数 5 替换 %d 。执⾏后的输出结果就是 I have 5 pears
•常⽤的占位符除了%d
,还有 %s
表⽰代⼊的是字符串
(字符串要用双引号括起来)
•上⾯⽰例中,%s
表⽰代⼊的是⼀个字符串,所以printf
的第⼆个参数就必须是字符串,这个例⼦是 five 。执⾏后的输出就是 I have five pears
•输出⽂本⾥⾯可以使⽤多个占位符
•上⾯⽰例中,输出⽂本%s have %d pears
有两个占位符,第⼀个是字符串占位符%s
,第⼆个是整数占位符 %d
,分别对应printf
的第二个参数mom
和第三个参数5
(%s have %d pears
是第一个参数),执⾏后的输出就是mom have 5 pears
•printf参数与占位符是⼀⼀对应关系,如果有 n
个占位符, printf
的参数就应该有 n +1
个(输出文本算一个参数)
。如果参数个数少于对应的占位符, printf
可能会输出内存中的任意值
3.大部分 占位符 列举
• %a
:⼗六进制浮点数,字⺟输出为⼩写
• %A
:⼗六进制浮点数,字⺟输出为⼤写
• %c
:字符 //char 类型
• %d
:⼗进制整数 // int 类型
• %e
:使⽤科学计数法的浮点数,指数部分的 e 为⼩写
• %E
:使⽤科学计数法的浮点数,指数部分的 E 为⼤写
• %i
:整数,基本等同于 %d
• %f
:⼩数(包含 float 类型和 double 类型)// float类型 %f
// double 类型%lf
• %g
:6个有效数字的浮点数。整数部分⼀旦超过6位,就会⾃动转为科学计数法,指数部分的 e
为⼩写
• %G
:等同于 %g ,唯⼀的区别是指数部分的 E 为⼤写
• %hd
:⼗进制 short int 类型
• %ho
:⼋进制 short int 类型
• %hx
:⼗六进制 short int 类型
• %hu
:unsigned short int 类型
• %ld
:⼗进制 long int 类型
• %lo
:⼋进制 long int 类型
• %lx
:⼗六进制 long int 类型
• %lu
:unsigned long int 类型
• %lld
:⼗进制 long long int 类型
• %llo
:⼋进制 long long int 类型
• %llx
:⼗六进制 long long int 类型
• %llu
:unsigned long long int 类型
• %Le
:科学计数法表⽰的 long double 类型浮点数
• %Lf
:long double 类型浮点数
• %n
:已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中
• %o
:⼋进制整数
•%p
:指针(⽤来打印地址)
•%s
:字符串
• %u
:⽆符号整数(unsigned int)
• %x
:⼗六进制整数
• %zd
: size_t 类型
• %%
:输出⼀个百分号
在使用这些占位符时,一定要互相匹配
4.输出格式
4.1限定宽度

•对于⼩数,这个限定符会限制所有数字的最⼩显⽰宽度
•上⾯⽰例中, %12f
表⽰输出的浮点数最少要占据12位。由于%f
的默认显⽰精度是⼩数点后6位,所以 123.4
输出结果的头部会添加2个空格
•同理我们也可以用0
来代替空格
4.2如何总是显示正负号
•printf
正数不显⽰ +
号(即使在打印的正数前加 +
也一样),负数显⽰-
号。如果想让正数也输出 +
号,可以在占位符的 %
后⾯加⼀个 +
•%+d
可以让输出数值带有正负号
4.3限定小数位数
•如果想要限定小数位可以使用%.nf
(n
代表限定的位数)
•下面的例子是保留小数点后三位,%.3f
•编译器会 四舍五入
•当小数位数过多时,编译器就可能无法准确表示
•限定小数位数与限定宽度占位符结合使⽤
•上⾯⽰例中,
%*.*f
的两个星号通过 printf
的两个参数 10
和 3
传⼊,可以使用变量配合%*.*f
来改变 宽度和小数位数了 ,更加灵活
4.4输出部分字符串
•%s
占位符⽤来输出字符串,默认是全部输出
•%.ns
指定输出的⻓度,其中 n
代表⼀个数字,表⽰所要输出的⻓度
•限定小数位数与限定宽度占位符在字符串也可以结合使用,同样也可以使用%*.*
来代替参数
5.printf的返回值
•printf
函数的返回值是成功输出的字符数
•上面的例子,第一个printf
先输出12
,第一个printf
成功输出两个字符,所以返回值是2
,那么r=2
,第二个printf
输出r
的值
二、scanf
1.在VS编译器使用scanf报错怎么办
看这一篇博文https://editor.csdn.net/md/?articleId=144182567
2.基本用法
•scanf
函数⽤于读取⽤⼾输⼊的数值
⽤⼾输⼊数据、按下回⻋键后, scanf
就会处理⽤⼾的输⼊,将其存⼊变量
•需要头⽂件stdio.h
。
•scanf
的语法跟 printf
类似
•基本形式
1 int i = 0;
2 scanf("%d",&i);
// %d表示要输入的数据类型, &表示取地址操作符,i是变量
•上⾯⽰例中, scanf
的第⼀个参数 %d
,表⽰⽤⼾输⼊的应该是⼀个整数。 %d
是⼀个占位符, %
是占位符的标志,d
表⽰整数。第⼆个参数 &i
表⽰,将⽤⼾输⼊的整数存⼊变量i
。
•变量前⾯必须加上 &
运算符(指针变量除外),因为 scanf
传递的不是值,⽽是地址,将变量i
的地址指向⽤⼾输⼊的值。
如果这⾥的变量是指针变量(⽐如字符串变量),那就不⽤加 &
运算符。
•scanf支持一次输入多个变量,一个变量输入完成需要空格隔开,才能输入下一个值
•字符串⾥⾯有多少个占位符,就有多少个变量
1 int a,b,c,d;
2 scanf("%d%d%d%d",&a,&b,&c,&d);
•scanf
处理数值占位符时,会⾃动过滤空⽩字符,包括空格、制表符(Tab
键)、换⾏符(\n
)
•⽤⼾输⼊的数据之间,有⼀个或多个空格不影响scanf
解读数据
•使⽤回⻋键,将输⼊分成⼏⾏,也不影响解读
•scanf
处理⽤⼾输⼊的原理是,⽤⼾的输⼊先放⼊缓存,等到按下回⻋键后,按照占位符对缓存进⾏解读
•每次按下回⻋键以后,scanf
就会开始解读,如果第⼀⾏匹配第⼀个占位符,那么下次按下回⻋键时,就会从第⼆个占位符开始解读
•解读⽤⼾输⼊时,会从上⼀次解读遗留的第⼀个字符开始,直到读完缓存,或者遇到第⼀个不符合条件的字符为⽌
•上⾯⽰例中,scanf
读取⽤⼾输⼊时,%d
占位符读取到 123
停下来,因为后⾯的 .
不属于整数的有效字符,这就是说,占位符 %d 会读到 123
。第⼆次调⽤ scanf
时,就会从上⼀次停⽌解读的地⽅,继续往下读取。这⼀次读取的⾸字符是.
,由于对应的占位符是 %f
,会读取到 .456
3.scanf的返回值
•scanf
的返回值是⼀个整数,表⽰成功读取的变量个数
•下面的例子中,scanf
成功读取了a
b
c
的值,成功读取的变量个数有3
个,所以r=3
•如果没有读取任何项,或者匹配失败,则返回 0
•下面的例子,变量a是整型变量,而输入的a是字符,scanf
匹配失败,所以a=0
,变量a匹配失败后,scanf
不会再往下匹配变量b和变量c,所以b=0
,c=0
,因为没有成功读取的变量个数,所以所以scanf
的返回值r=0
•scanf从匹配失败的变量开始,不会再往后匹配未匹配的变量,后面的变量的值一律为 0
•下面的例子中,变量b是整型变量,而输入的#是字符,scanf
匹配失败,变量b匹配失败后,scanf
不会再往下匹配变量c,所以c=0
,只成功读取到变量a,所以scanf
的返回值r=1
•如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到⽂件结尾,则返回常量 EOF (-1)
。
•EOF --> end of file
⽂件结束标志
•如果想要提前结束,按 ctrl+z
•在VS编译器中,需要按3次 ctrl+z
才会结束(每按完一个都需要按一次回车键
•下面例子中,scanf
成功读取到两个变量,scanf
的返回值r=2
•下面例子中,scanf
没有读取到任何变量,scanf
的返回值是EOF(-1)
所以r=-1
4.占位符
•scanf
的占位符与printf
的基本上一致(没有完全列出):
• %c
:字符 //char 类型
• %d
:⼗进制整数 // int 类型
• %f
:⼩数(包含 float 类型和 double 类型)// float类型 %f
// double 类型%lf
• %hd
:⼗进制 short int 类型
• %ho
:⼋进制 short int 类型
• %hx
:⼗六进制 short int 类型
• %hu
:unsigned short int 类型
• %ld
:⼗进制 long int 类型
• %lo
:⼋进制 long int 类型
• %lx
:⼗六进制 long int 类型
• %lu
:unsigned long int 类型
• %lld
:⼗进制 long long int 类型
• %llo
:⼋进制 long long int 类型
• %llx
:⼗六进制 long long int 类型
• %llu
:unsigned long long int 类型
• %n
:已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中
• %o
:⼋进制整数
•%s
:字符串
• %u
:⽆符号整数(unsigned int)
• %x
:⼗六进制整数
•%[]
:在⽅括号中指定⼀组匹配的字符(⽐如 %[0-9]–>ASCLL码值 ),遇到不在集合之中的字符,匹配将会停⽌
4.1特殊%c
•以上占位符除了%c
以外,都会忽略起首的空格
•以%d
为例
•%c
不忽略空⽩字符,总是返回当前第⼀个字符,⽆论该字符是否为空格
•如果要强制跳过字符前的空⽩字符,可以在%c
前加上⼀个空格,表
⽰跳过零个或多个空⽩字符,scanf(" %c",%a);
4.2特殊%s 和 限定scanf读取个数
•%s
从当前第⼀个⾮空⽩字符开始读起,直到遇到空⽩字符(即空格
、换⾏符\n
、制表符Tab键
等)为⽌
•上面例子中,scanf
先跳过qwer
之前的空格,遇到第一个⾮空⽩字符q
开始读起,scanf
读到空格后停下,所以输出的是qwer
•scanf
不适合读取可能包含空格的字符串
•如果想要跳过空白字符打印输入的所有字符,可以这样写
scanf("[^\n]s",arr);
,表示遇到换行符\n
才会停止读取,输入完成后按回车键换行(表示换行),scanf
读取停止
•scanf
将字符串读⼊字符数组时,不会检测字符串是否超过了数组⻓度。所以,储存字符串时,很可能会超过数组的边界,导致预想不到的结果。为了防⽌这种情况,使⽤ %s
占位符时,应该指定读⼊字符串的最⻓⻓度,即写成 %ns
,其中的n
是⼀个整数,表⽰读取字符串的最⼤⻓度,后⾯的字符将被丢弃
•限定scanf
读取个数不只是在%s
可以用,在其他占位符也可以这样使用
5.scanf输入格式 与 赋值忽略符
5.1输入格式
•先看一个例子
•代码scanf("%d-%d-%d", &a, &b, &c);
占位符是"%d-%d-%d"
,指定了输入的格式,输入的数据需要符号-
隔开,而我们输入的12 34 32
,数字之间是用空格隔开,输入的格式与指定的格式不匹配,导致无法正确读取所有的数值
•当我们输入的是12-34-32
,scanf
便可以正常读取
•如果指定了scanf的输入的格式,在输入数据时,应该遵守设定的输入格式,以防止出现错误
5.2赋值忽略符
•scanf
提供了⼀个赋值忽略符*
只要把 * 加在任何占位符的百分号后⾯,该占位符就不会返回值,解析后将被丢弃
•%*c
忽略字符
•上⾯⽰例中, %*c
就是在占位符的百分号后⾯,加⼊了赋值忽略符 *
,表⽰这个占位符没有对应的变量,解读后不必返回