scanf默认输入数据长度大于输入数据实际长度,导致其他数据被覆盖问题

为了节省内存空间,定义了几个unsigned short和unsigned char类型,但是使用scanf函数读入其中一个数据时,

其他数据被误覆盖。代码如下:

#include <stdio.h>
#include <stdlib.h>

  

int main(void)
{
	unsigned short a = 0x5BA2;
	unsigned short b = 0x12;
	unsigned short c = 0x34;
	unsigned char  d = 0x94;	
	 
		
	printf("Input a:");
	
	scanf("%x",&a);
	
    printf("Result:\n");
    printf("a = %X\n",a);
    printf("b = %X\n",b);    
	printf("c = %X\n",c);
	printf("d = %X\n",d);
	

}

运行结果为:

可以看到b的值被改成了0,并且有一个告警:'%x'期望得到'unsigned int*'类型的数据,但是传入的参数为"short unsigned int*' .

看告警是scanf要求的数据类型和传入的数据类型不匹配导致的。

查看下'unsigned int'和'short unsigned int'的大小,以及a,b,c,d分配的内存地址。

#include <stdio.h>
#include <stdlib.h>

  

int main(void)
{
	unsigned short a = 0x5BA2;
	unsigned short b = 0x12;
	unsigned short c = 0x34;
	unsigned char  d = 0x94;	
	 
		
	//printf("Input a:");
	
	//scanf("%x",&a);
	
	printf("size of unsigned short: %d\n", sizeof(unsigned short));
	printf("size of unsigned short: %d\n", sizeof(unsigned int));
	
	printf("Address:\n");
    printf("&a = %X\n",&a);
    printf("&b = %X\n",&b);    
	printf("&c = %X\n",&c);
	printf("&d = %X\n",&d);
	
    printf("Result:\n");
    printf("a = %X\n",a);
    printf("b = %X\n",b);    
	printf("c = %X\n",c);
	printf("d = %X\n",d);
	

}

编译运行程序:

可以看到,'unsigned int' 为4个字节大小,'short unsigned int'为2个字节大小。

a的内存地址为:8136FB1A
b的内存地址为:8136FB1C
c的内存地址为:8136FB1E
d的内存地址为:8136FB19

可以看到a,b,c的内存地址是连续的,d在定义时,放在了最后,但是内存地址却在最前面。c语言的编译器在

分配内存时,不只是按照变量的定义顺序来分配的,而且还参考了变量的类型。

由a、b、c的地址,可以计算出a、b的大小都是2个字节。

而scanf("%x",&a);语句会将a的值扩展为4个字节数,会将a后面的数,即b给覆盖掉。

查找scanf的相关资料,对scanf语句的格式进行修改。使用scanf("%hx",&a);可以将输入的数限定为2个字节的长度,

和输入数的定义长度保持一致就会避免该问题。

scanf() 格式控制符汇总

格式控制符说明
%c读取一个单一的字符
%hd、%d、%ld读取一个十进制整数,并分别赋值给 short、int、long 类型
%ho、%o、%lo读取一个八进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型
%hx、%x、%lx读取一个十六进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型
%hu、%u、%lu读取一个无符号整数,并分别赋值给 unsigned short、unsigned int、unsigned long 类型
%f、%lf读取一个十进制形式的小数,并分别赋值给 float、double 类型
%e、%le读取一个指数形式的小数,并分别赋值给 float、double 类型
%g、%lg既可以读取一个十进制形式的小数,也可以读取一个指数形式的小数,并分别赋值给 float、double 类型
%s读取一个字符串(以空白符为结束)

修改后的相关代码:

#include <stdio.h>
#include <stdlib.h>

  

int main(void)
{
	unsigned short a = 0x5BA2;
	unsigned short b = 0x12;
	unsigned short c = 0x34;
	unsigned char  d = 0x94;	
	 
		
	printf("Input a:");
	
	scanf("%hx",&a);

	
    printf("Result:\n");
    printf("a = %X\n",a);
    printf("b = %X\n",b);    
	printf("c = %X\n",c);
	printf("d = %X\n",d);
	

}

 运行结果:

结果中输入之已经对其他变量不产生影响了。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WangLanguager

您的鼓励是对我最大的支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值