c-读取%d格式说明符时char和short数据类型的行为



我正在尝试执行"钻头操作"操作(不带任何位运算符(。在这样做的时候,我遇到了一些小错误,即,如果我使用";char";以及";短";数据类型我无法获得所需的输出,相反,如果我使用";int";数据类型我得到了想要的输出。因此,当读取带有%d的char或short数据类型变量时,我不明白scanf((中发生了什么。这里的"num1"变量将存储用户输入的数字,"pos"变量存储位位置&ampval"是存储需要替换的值"0"或"1"的变量。

通过使用char/short数据类型,它读取的是用户输入的正确位置值,但在"switch"语句中,它将";默认";条件但当我使用"int"数据类型时,在switch语句中,它将更正大小写标签。

代码:

int main()
{
union bit_operations
{
unsigned char num;
struct bit_field
{
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
unsigned char b8:1;
}p;
}u;


unsigned char num1;
char pos,val;
printf("enter the numn");
scanf("%x",&num1);
u.num=num1;
printf("value entered is %xn",u.num);

while(1){
printf("enter bit position(in range 1-8)n");
scanf("%d",&pos);

printf("pos value is %dn",pos);

printf("For SET->1nFor REST->0n");
scanf("%d",&val);

switch(pos)
{
case 1: u.p.b1=val;
printf("0X%Xn",u.num);
break;
case 2: u.p.b2=val;
printf("0X%Xn",u.num);
break;

case 3: u.p.b3=val;
printf("0X%Xn",u.num);
break;
case 4: u.p.b4=val;
printf("0X%Xn",u.num);
break;

case 5: u.p.b5=val;
printf("0X%Xn",u.num);
break;
case 6: u.p.b6=val;
printf("0X%Xn",u.num);
break;
case 7: u.p.b7=val;
printf("0X%Xn",u.num);
break;
case 8: u.p.b8=val;
printf("0X%Xn",u.num);
break;
default:printf("entered wrong bit position");

}


}
return 0;
}

这是输出:-

enter the num
ff
value entered is ff
enter bit position(in range 1-8)
4
pos value is 4
SET->1
REST->0
0
entered wrong bit position
enter 10 to EXIT
or
enter bit position(in range 1-8)

提前感谢。。。

定义如下:https://en.cppreference.com/w/c/io/fscanf

如果转换规范无效,则行为为未定义

转换说明符%d%x用于

有符号的int*或无符号的int*

即不适用于char*,即对其无效。

因此;读取%d格式说明符"时char和short数据类型的行为;未定义。

对于scanfunsigned char,您需要在格式说明符内使用适当的长度修饰符

unsigned char num1;
char pos,val;
int r = scanf("%hhx", &num1);
if (r) abort(); // scanf _may_ fail. Do not forget to handle errors.
r = scanf("%hhd", &pos);
if (r) abort(); // scanf _may_ fail. Do not forget to handle errors.
r = scanf("%hhd", &val);
if (r) abort(); // scanf _may_ fail. Do not forget to handle errors.

hh长度修饰符使scanf根据说明符扫描unsigned charsigned char

请注意,printf不需要hh。这是C的一个怪癖,因为变参数列表中的每个参数都经历了隐式整数提升。

最好的方法根本不关心编译器警告。始终尝试在编译中启用所有警告。在godbolt上使用gcc-Wall-Wextra编译时,您的代码将产生:

<source>: In function 'main':
<source>:26:13: warning: format '%x' expects argument of type 'unsigned int *', but argument 2 has type 'unsigned char *' [-Wformat=]
26 |     scanf("%x",&num1);
|            ~^  ~~~~~
|             |  |
|             |  unsigned char *
|             unsigned int *
|            %hhx
<source>:32:13: warning: format '%d' expects argument of type 'int *', but argument 2 has type 'char *' [-Wformat=]
32 |     scanf("%d",&pos);
|            ~^  ~~~~
|             |  |
|             |  char *
|             int *
|            %hhd
<source>:37:13: warning: format '%d' expects argument of type 'int *', but argument 2 has type 'char *' [-Wformat=]
37 |     scanf("%d",&val);
|            ~^  ~~~~
|             |  |
|             |  char *
|             int *
|            %hhd
Compiler returned: 0

我认为写一个并集,然后把它传递给大胖子switch没有什么意义。代码基本上就是这样:

if (1 <= pos && pos <= 7) {
u.num = 1 << (pos - 1);
// or maybe you want MSB order, like:
// u.num = 1 << (8 - pos);
printf("0X%Xn", u.num);
} else {
// wrong pos;
}

最新更新