百变Scanf()的千层套路

一、格式化输入

1、%c:

scanf()中最为诡计多端的就是字符类型的输入了,下面编写了一个简易程序,来看看scanf()是怎么处理字符的吧~

#include<stdio.h>

int main(void)
{
	int s;
	char c;
	while (1)
	{
		s = scanf_s("%c",&c);
		printf("此时存入的字符是:%c\n", c);
		printf("scanf_s返回值是:%d\n",s);
				
	}

	return 0;
}

(注:该程序仅为测试用,故循环没有出口。)

1)char类型占一字节,故每次不管输入多少字节,只能存入一个字节,返回值仍为1,剩余的不删除,存在缓冲区中,留着下次输入用;

2)char不跳过空白字符(退格,空格,回车),皆可存入且输出,返回值皆为1;

 3)插入不能直接读取负数,会把负号和数字分开存入;

 4)因为中文占两字节,所以无法成功存入,但会被拆分成两个字节分别存在参数和缓冲区中,返回值仍为1;

2、%d:

#include<stdio.h>

int main(void)
{
	int s,d;
	char c;
	while (1)
	{
		s = scanf_s("%d",&d);
		printf("此时存入的数字是:%d\n", d);
		printf("scanf_s返回值是:%d\n",s);
		
	}
	
	return 0;
}

1)输入字符:存在两种情况

情况一:int d未初始化,程序将一个溢出值赋给d(我们甚至还可以对带着溢出值的d进行操作),scanf返回值为0;

情况二:假如我们给int d一个初始值,我们会发现,数值d的值不会被该溢出值改变,scanf返回值为0。

值得注意的是,无论d的值有没有被溢出值改变,无效字符q都会被扔到缓冲区中,这点我们会在下文混合输入字符和数字时看到。

3、字符与数字混合输入:

现在来看看字符和数字会摩擦出怎样的火花吧~

1)先字符后数字型:

#include<stdio.h>

int main(void)
{
	int s,d;
	char c;
	while (1)
	{
		s = scanf_s("%c%d",&c,1,&d);//注意scanf_s在混合输入时要在c后面加个输入长度。
		printf("此时存入的字符和数字是:%c和%d\n", c,d);
		printf("scanf_s返回值是:%d\n",s);
		
	}

	return 0;
}

 ps:不明白为什么要在c后面加个长度的说,c不是都是1个字节吗。。

可以看到,当输入12q时,1被存入c,2被存入d,q 和\n在缓冲区,接下来,q被存入c,但是由于%d会跳过\n,因此程序要求客户再次输入,发现了qq,因为d已经有有效值2了,故不将q对应的溢出值存在d中,并把两个q扔到缓冲区,所以我们可以发现接下来q被打印了两次。

因此scanf接受信息的顺序其实是这样的:

12\qq\qw\w?

2)先数字后字符:

#include<stdio.h>

int main(void)
{
	int s,d;
	char c;
	while (1)
	{
		s = scanf_s("%d%c", &d,&c,1);//注意scanf_s在混合输入时要在c后面加个输入长度。
		printf("此时存入的数字和字符是:%d和%c\n", d, c);
		printf("scanf_s返回值是:%d\n", s);

	}

	return 0;
}

情形1:

 第二个q无效,被扔到缓冲区,但是scanf的返回值为2;接下来,q不断被%d读取错误,原先的d和c的值都不被改变。

情形2:

只要前面是数字,就会被视为数字而不是字符。

情形3:

1和换行符在第一次输入时被扔到缓冲区供第二次输入使用。

3、%f:     

输入字符:跟%d一样,只不过溢出值有小数点而已。   

返回值:输入整型数时返回值是1。            

总结:

1、scanf只有往%d或%f里打字符时返回值才为0,往%c里打数字时数字会被视为字符,没有影响,多打多余的会被扔到缓冲区里,返回值还是不受影响。

2、往%d里打字符时,若已有值,则值不改变,否则变为溢出值。

3、若用scanf_s输入多个值,要在%c后面加个,1,。

 4、%d会吃掉它前面的空白字符,但是不会吃掉它后面的空白字符

二、getchar()

1、getchar()或char c=getchar()的返回值是对应的输入字符;

2、单打getchar()可以吃掉一个字符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值