C语言—printf和scanf详解(万字笔记更新中....)
Tom 2024-10-10 10:05:02 阅读 96
在写c语言时,printf和scanf是我们必不可少且常用的关键字,相信大多数人对它们俩的认识只是停留在表面上,并没有深入了解过它们吧,那么这一篇文就来深入对它们俩来说道说道
Printf
Printf:输出函数,将参数输出到屏幕上
案例:
{
printf("hello \nworld\n");
return 0;
}
printf("hello \nworld\n"):将hello word打印到屏幕上,在使用printf函数时可以多次使用换行符\n,想在哪里加都可以
|
占位符
占位符:在printf中,占位符可以被指定的数值替换
案例:
int main()
{
printf("there are 3 apples\n");……1
printf("there are %d apples\n", 3);……2
printf("there are %d apples\n", 6);……3
printf("%s will come to tonight\n", "李四");……4
printf("%s says it is %d O'clock\n", "lisi", 21);……5
return 0;
}
1和2、3的区别是1这一代码的数字3是不能改变的,而且2/3语句中因为使用了占位符%d,所以是可以改变相应数字的,只需要将后面的数字更改为定义的变量就可以4这句代码中,%s代表字符占位符,可以输入相应的字符,注意字符要用双引号5这句代码中混合使用了字符占位符和整型占位符,可以输入相应的内容,注意后面输入的内容的顺序和前面的占位符的顺序要相同
|
常见占位符
%a
| ⼗六进制浮点数,字⺟输出为⼩写
|
%A
| ⼗六进制浮点数,字⺟输出为⼤写
|
%c
| 字符
|
%d
| ⼗进制整数
|
%e
| 使⽤科学计数法的浮点数,指数部分的 e 为⼩写
|
%E
| 使⽤科学计数法的浮点数,指数部分的 E 为⼤写
|
%i
| 整数,基本等同于 %d
|
%f
| ⼩数(包含 float 类型和 double 类型)
|
%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 类型
|
%%
| 输出⼀个百分号
|
限定宽度
限定宽度:限定占位符的最小宽度
案例:
{
printf("%5d\n", 123);
printf("%-5d\n", 123);
printf("%12f\n", 123.45);
printf("%12f\n", 123.45);
return 0;
}
printf("%5d\n", 123);printf("%-5d\n", 123):以十进制的方式打印,让输出的值有5位宽,但现在只有3位宽,那么就默认在前面加2个空格以达到最小5位,那么在将5变为-5意思是将空格补到右边如结果图所示printf("%12f\n", 123.45):用十进制的方式打印,限定12位宽,现在有6位宽了(小数点也算一位)又因为小数默认有6位,所以系统会在前面加上2位空格已达到最小12位宽
|
结果:
总是显示正负号
让正负号显示出来,但其实默认负号本身就要显示,所以可以说是怎么显示正号
案例:
{
printf("%+d\n", 12);
printf("%+d\n", -12);
return 0;
}
printf("%+d\n", 12):以十进制的方式打印12,+d的意思就是在12前面显示正号printf("%+d\n", -12):以十进制的方式打印-12,+d在-12前加入正号,但-12是负数,有负号了,故最终还是-12
|
限定小数位
限定小数位:因为小数默认显示6位,但我们是可以进行限定小数后面的位数的
案例:
int main()
{
printf("%f\n", 123.45);
printf("%.2f\n",123.45);
printf("%6.2f\n", 0.5);
printf("%*.*f\n",6,2,0.5);
return 0;
}
printf("%.2f\n",123.45):以浮点数的形式打印123.45,在%和f中间加上一个 . 就是表示限定小数后面的位数了,想要几位就在 .后面输入数字就行,比如现在是.2表示显示2位小数printf("%6.2f\n", 0.5):以浮点数的形式打印0.5,,那么6.2中的6表示总共6位宽,小数点后有2位printf("%*.*f\n",6,2,0.5):以浮点数的形式打印0.5,,*.*表示总位宽和小数位宽由后面输入的值确定,也就是后面的6和2
|
注意:如果限定的位数大于实际位数,系统会补上零
输出部分字符串
输出部分字符串:%s占位符用来输出字符串,默认是全部输出。如果如果只想输出开头的部分,可以⽤ %.[n]s指定输出的⻓度,其中[m]代表⼀个数字,表⽰所要输出位宽
案例:
{
printf("%.5s\n", "hello world");
return 0;
}
printf("%.5s\n", "hello world"):以字符串的形式打印hello world,.5表示只要5位宽,和上面的概念一样,故最终结果就只有 hello
|
那么对printf的解说就结束了
Scanf
Scanf:定义了变量后,scanf可以接受用户输入的内容并且存放到指定位置
案例:
{
int a = 0;
printf("请输入成绩:");
scanf("%d", &a);
printf("成绩=%d", a);
return 0;
}
int a = 0:定义一个整型变量a,初始化位0printf("请输入成绩:"):在屏幕上打印请输入成绩:scanf("%d", &a):scanf将等待用户输入整型数值,并且将输入的值存放在整型变量a中printf("成绩=%d", a):以十进制的方式将刚刚输入的a在值打印出来,并在前面加上成绩=
|
注意:遇到scanf的安全问题请参考“变量的使用中注意”来解决,然后不要忘了scanf有取地址符号&
基本用法
Scanf的语法和printf的语法基本相同,还有scanf()必须提前知道数据的整型,也就是%什么,语句中有几个占位符,就必须有几个变量
案例:
int main()
{
int a = 0;
int b = 0;
float x = 0.0;
float y = 0.0;
scanf("%d %d %d %f %f", &a, &b, &x, &y);
printf("%d %d %d %f %f", a, b, x, y);
return 0;
}
int a = 0;int b = 0;float x = 0.0; float y = 0.0:定义整型变量a和b,浮点数x和y,都初始化为0scanf("%d %d %d %f %f", &a, &b, &x, &y):scanf等待用户输入内容,并且将内容存放在指定位置,这里的%d%f之间其实可以不用空格,但用户在输入数值的时候每组数值要空格,不让会识别成一组是数值printf("%d %d %d %f %f", a, b, x, y):分别就输入的值按照格式打印出来
|
注意:scanf函数不能加\n,并且用户输入时,要空格或用制表符或回车
补充:scanf函数再处理占位符时,会自动过滤空白字符,空格,回车,换行,制表符
补充:处理⽤⼾输⼊的原理是,⽤⼾的输⼊先放⼊缓存,等到按下回⻋键后,按照占位符对缓存进⾏解读。解读⽤⼾输⼊时,会从上⼀次解读遗留的第⼀个字符开始,直到读完缓存,或者遇到第⼀个不符合条件的字符为⽌。
案例:
int main()
{
int x;
float y;
// ⽤⼾输⼊ " -13.45e12# 0"
scanf("%d", &x);
scanf("%f", &y);
printf("%d\n", x);
printf("%d\n", y);
return 0;
}
int x;float y:第一整型变量x和浮点数yscanf("%d", &x);scanf("%f", &y):scanf接受用户输入整型并存到x,scanf接受用户输入浮点数并存放到yprintf("%d\n", x);printf("%d\n", y):以相应的形式对应x和y
此时我们运行程序并且输入:-13.45e12# 0,然后是scanf是这样运行的,将-13存放在x中,因为整型没有小数,所以第一个scanf就结束运行,并且将-13存入x;此时第二个scanf开始接着小数点开始运行,因为scanf会从上一个遗留的第一个字符开始,并且以此为起点开始找小数,也就是 . 开始,那么就找到了.45e12(这个是科学计数法,是0.45*10^12,可能有误差)然后遇到#结束,因为小数里没有#,将结果存放y
|
Scanf的返回值
Scanf的返回值:scanf的返回值是一个整型,表示成功读取的变量个数,如果没有读取任何项,或则匹配失败,则返回0,如果在成功读取任何数据之前,发生了读取错误或者遇到读取到文件结尾,则返回常量EOF
案例:
int main()
{
int a = 0;
int b = 0;
float f = 0.0f;
int r = scanf("%d %d %f", &a, &b, &f);
printf("a=%d b=%d f=%f\n", a, b, f);
printf("r = %d\n", r);
return 0;
}
int r = scanf("%d %d %f", &a, &b, &f):scanf接受用户输入的值,并且存放到相应位置,然后定义一个整型变量r来存放scanf的返回值,此时r=3,因为scanf里放了3个变量printf("a=%d b=%d f=%f\n", a, b, f); printf("r = %d\n", r):以指定形式打印相应内容
|
注意:如果此时想让r=2,那么就可以在运行时只输入两组数据,然后安ctrl+z,但由于vs的bug,vs环境下需要按3次ctrl+z
EOF:end of file 文件的结束,EOF的值为-1,在上面的例子中,如果什么都不输入按ctrl+z后回车 那么r此时就等于-1
占位符
占位符:scanf的占位符和printf的占位符相似
%[]
| 在方括号中指定一组匹配的字符(比如%[0-9]),遇到不在集合之中的字符,匹配将会停止
|
上⾯所有占位符之中,除了 %c 以外,都会⾃动忽略起⾸的空⽩字符。 %c 不忽略空⽩字符,总是返 回当前第⼀个字符,⽆论该字符是否为空格
案例:
{
char x = 0;
scanf("%c", &x);
printf("%c", x);
printf("xxxx");
return 0;
}
此时我们输入空格a,那么scanf中的%c会把空格给读取走,不会读取a了所以此时打印出来的就是 xxxx 如果要强制跳过%c读取空格,可在scanf中的%c前加空格
|
下⾯要特别说⼀下占位符 %s ,它其实不能简单地等同于字符串。它的规则是,从当前第⼀个⾮空⽩ 字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)为止
案例:
{
char x[20] = { 0 };
scanf("%s", x);
printf("%s", x);
return 0;
}
char x[20] = { 0 }:定义字符型数组x,且数组有20个,初始化为0此时我们输入ABC DEF,那么最终会打印出DEF,因为scanf %s 的形式遇到空格就不在继续读取了
|
因为 %s 不会包含空⽩字符,所以⽆法⽤来读取多个单词,除⾮多个 %s ⼀起使⽤。这也意味着, scanf() 不适合读取可能包含空格的字符串,⽐如书名或歌曲名。另外, scanf() 遇到 %s 占位 符,会在字符串变量末尾存储⼀个空字符 \0
scanf() 将字符串读⼊字符数组时,不会检测字符串是否超过了数组⻓度。所以,储存字符串时, 很可能会超过数组的边界,导致预想不到的结果(系统会提示崩溃)。为了防⽌这种情况,使⽤ %s 占位符时,应该指定 读⼊字符串的最⻓⻓度,即写成 %[n]s ,其中的 [n] 是⼀个整数,表⽰读取字符串的最⼤⻓度,后⾯的字符将被丢弃(这就是scanf不安全的原因)
案例:
int main()
{
char x[5] = { 0 };
scanf("%4s", x);
printf("%s\n", x);
return 0;
}
char x[5] = { 0 }:定一个数组为5的整型变量x,初始化为0scanf("%4s", x):强制让字符串的长度为4位宽,多余的会被截掉此时我们输入ABCDF,最终打印出ABCD
|
赋值忽律符
赋值忽律符:有时,⽤⼾的输⼊可能不符合预定的格式
案例:
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d-%d-%d", &year, &month, &day);
scanf("%d%*c%d%*c%d", &year, &month, &day);
return 0;
}
定一个scanf在用户输入的时候也必须将—输入进去,不然就不对而第二个scanf使用了赋值忽律符,此时用户只需要输入一组数值后按空格或制表符或回车就行了,不需要输入— 此时%*c就是赋值忽律符
|
好了,关于printf和scanf的讲解都结束了
如有错误请指出
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。