说到printf和scanf函数想必大家都不陌生吧,大多数初学者都了解一个是输入函数一个是输出函数,但是很多人对其了解仅限于此,其实不然。printf作为输出函数,其输出的方式有多种多样,同样scanf函数也是如此,不同的输入和输出方式,其在屏幕上的输出效果也会不同,今天这篇博客定会让你耳目一新,并且彻底搞明白!!!
printf
常见的格式控制符:
%d:用于输出整型数(整型指本质为整型的数,如int、short等)
%c:用于输出一个字符
%s:用于输出一个字符串
%o:以无符号八进制形式输出整数值
%x:以无符号十六进制形式输出整数值
%u:以无符号形式输出十进制数
%f:用来输出浮点数(float),精度为6位小数,第七位四舍五入。
%p:指针的值(即地址)
这是一些常见的输出字符格式串,这里不在进行详细介绍,本篇博客主要讲解一些关于输出占位和对齐的相关问题!
1.占位长度与格式串搭配
(1)与%d搭配
%md:m为指定的输出数据的位宽。如果数据的位数小于m,则左端补以空格(因为默认右对齐,所以左补用以占位);如果数据的位数大于m,则以数据的实际位数输出。示例如下:
int main()
{
int a = 1234567;
printf("%4d\n", a);
printf("%10d\n", a);
return 0;
}
第一个输出位数小于数据实际长度,此时以数据实际长度进行输出,故结果为1234567;
第二个输出位数大于数据实际长度,此时输出数据时按照右对齐,左端以空格补齐;
(2)与%s搭配
%ms:m为指定的输出字符串的宽度。如果字符串的位数小于m,则左端补空格;如果字符串的位数大于m,则以实际的字符串长度输出。示例如下:
int main()
{
char arr[] = "abcdef";
printf("%5s\n", arr);
printf("%10s\n", arr);
return 0;
}
第一个字符串输出位数小于字符串实际长度,此时以字符串实际长度进行输出,故结果为abcdef;
第二个字符串输出位数大于字符串实际长度,此时字符串按照右对齐进行输出,左端以空格补齐;
(3)
%m.ns:意为从左向右截取字符串的n位输出到占位m的位置,左补空。示例如下:
int main()
{
char arr[] = "abcdef";
printf("%3.4s\n", arr);
printf("%6.4s\n", arr);
return 0;
}
第一个%3.4s,输出的字符串位数为m=3,而截取的字符串位数为n=4,m<n,以截取的实际位数输出,故结果为abcd;
第二个%6.4s,输出的字符串位数为m=6,而截取的字符串位数为n=4,m>n,以截取的实际位数按照右对齐输出,其左端空格补齐;
(4)与%f搭配
%m.nf:m为占位宽度,n为小数点右边的位数,浮点数的规则较字符串比起来更为复杂些,你不但要关注浮点数的总占位宽,还要关注小数的占位宽。
整数部分完整输出,唯一要注意的是:
当m>(整数位宽+小数点位宽+n)时,左补空。
int main()
{
float a = 1;
float b = 3.14;
float c = 3.14159;
printf("%f\n", a);
printf("%4.4f", b);
printf("%8.4f\n", b);
printf("%4.4f\n", c);
return 0;
}
第一个%f,即正常输出小数点后6为,不满6为的话直接用0补齐,故结果为1.000000;
第二个%4.4f,浮点数所占位数为m=4<6(浮点数总位数)则正常输出,且小数点后为4位,不满4位则用0补齐;
第三个%8.4f,浮点数所占位数为m=8>6(浮点数总位数)则按照又对齐输出,左端用空格补齐,且小数点后为4位,不满4位则用0补齐;
第四个%4.4f,浮点数所占位数为m=4<6(浮点数总位数)则正常输出,且小数点后为4位,超过4位则需要在第5位按照四舍五入进行输出,故结果位3.1416;
2.对齐以及补0问题
第一个模块说明了一些占位相关的操作,我们也可以发现当我们输出所提供的位数大于数据的实际位数时,在屏幕上输出打印的时候都会按照右对齐的方式打印,且左端都是以空格补齐,这是为什么呢?下面我们一起来揭晓:
+/-:+一般表示输出时按照右对齐,-一般表示输出时按照左对齐,但是+一般我们都不加上(即默认按照右对齐),所以这也是为什么上面的输出按照右对齐输出的原因了,而按照左对齐输出时,-必须带上,如”%-5d\n”,这说明按照左对齐输出5个位数;
%0…:%0…表示输出的时候位数不足时则左端自动补0,比如说“%02d\n”,这说明输出的位数占2位,不足两位时左端需要补0;
示例如下:
int main()
{
char arr[] = "abcdef";
printf("%-10s\n", arr);
printf("%10s\n", arr);
int a = 1;
printf("%02d\n", a);
return 0;
}
第一个和第二个输出时一个带了-,一个没有带,当输出所占位数大于实际位数时,第一个带了-的输出结果按照左对齐的方式输出,右端空格补齐;而不带-的则按照右对齐进行输出,左端空格补齐;
第三个%02d,说明需要输出两个位数的结果,而定义的变量a=1,仅占一个位数,所以左端需要以0补齐;
scanf
scanf函数的一般形式为: scanf(“格式控制字符串”, 地址表列);
其中,格式控制字符串的作用与printf函数相同,但不能显示非格式字符串,也就是不能显示提示字符串。地址表列中给出各变量的地址。地址是由地址运算符“&”后跟变量名组成的。例如:&a、表示变量a的地址。
(1)scanf与%d搭配时
scanf与%d搭配的方式有很多种,我们这里主要讲解常用的3种;
第一种:单独的%d,即类似于(scanf(”%d“,&a))这种,这也是最简单的一种,可以理解位为在内存中开辟了一块空间存储变量a,&a就是变量a的地址,一定要带上取地址符号;
int main()
{
int a = 0;
int b = 0;
int c = 0;
int d = 0;
scanf("%d%d", &a, &b);
scanf("%d %d", &c, &d);
int sum = a + b;
int ret = a - b;
printf("%d\n", sum);
printf("%d\n", ret);
return 0;
}
这里我写了两种scanf函数输入的方式,第一种%d%d连在一起第二种%d %d中间加了一个空格,其实效果是一样的,我这么写想加深大家对scanf需要输入格式串字符的了解,第一种情况的话当我们输入一个值的时候,可以通过空格符或者enter键来跳到第二个值的输入(想要深入了解的话得知道一些内存和缓冲区的知识,不过多赘述);而第二种情况只需手动打入与scanf里面所输入的格式一样即可,即第一个值+空格符+第二个值。
注:scanf函数的输入相当严格,你在scanf中输了非格式字符串,你编译的时候也得输入相同的非格式字符串,如:你敲的是scanf(”a=%d“,&a),你输入的时候也必须输入a=某个值,这样才能正确编译。
第二种:%d与占位字符搭配,如%4d%4d,这表明你输入的一串数字前4个数字赋给第一个变量,接下来的4个数字赋给第二个变量,示例如下:
int main()
{
int a = 0;
int b = 0;
scanf("%4d%4d", &a, &b);
printf("%d\n%d\n", a, b);
return 0;
}
当输入123456789时,先截取前4个数字1234赋给变量a,所以输出a=1234,再截取接下来的4个数字赋给变量b,所以输出b=5678,剩余的数字舍弃不进行输出。
第三种:%*d,如%d%*d%d,这表明输入三个数字时,会跳过第二个变量直接给第三个变量赋值,示例如下:
int main()
{
int a = 0;
int b = 0;
scanf("%d%*d%d", &a, &b);
printf("%d\n%d\n", a, b);
return 0;
}
我们可以看到当我们输入123时,会自动跳过2把3赋给变量b,故输出结果为1 3。
(2)scanf与%c搭配
当用scanf输入字符时,只需记住一点即可,在输入字符数据时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符。
示例如下:
int main()
{
char ch1 = 'a';
char ch2 = 'b';
char ch3 = 'c';
scanf("%c%c%c", &ch1, &ch2, &ch3);
printf("%c\n%c\n%c\n", ch1, ch2, ch3);
return 0;
}
两次输入的字符都是def为什么编译结果不一样呢?因为我刚才上面说过了在输入字符数据时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符。第一次输入的时def故每个字母均是一个字符,而第二次输入的是d e f,输入了空格字符串,系统会自动默认第二个字符输入的为空格故输出结果为d e。
现在我们已经学完了有关printf和scanf函数的一些深入用法,下面让我们一起来一起做一道OJ题目吧,这也是我之前刷到的一个题目,这个题目可以充分的展示今天所学习的这些用法。
#include <stdio.h>
int main()
{
int year = 0;
int month = 0;
int date = 0;
scanf("%4d%2d%2d",&year,&month,&date);
printf("year=%d\nmonth=%02d\ndate=%02d\n",year,month,date);
return 0;
}
这是我的答案,仅供参考!!!
感谢关注,继续加油!!!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/89473.html