深入讲解printf和scanf格式控制符

说到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;
}

这是我的答案,仅供参考!!!

感谢关注,继续加油!!!

  • 20
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值