关于char型与unsigned char型数据使用格式化输出注意点

  在使用 socket(AF_INET, SOCK_DGRAM, 0); 打开一个套接字流,通过 ioctl(s, SIOCGIFHWADDR, &ifr) 获取网卡的mac地址的时候,需要将 struct ifreq ifr; 结构体中 ifr.ifr_hwaddr.sa_data 数组中的信息按照十六进制提取到字符串中去,程序中使用到了

sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X",
            ifreq.ifr_hwaddr.sa_data[0],
            ifreq.ifr_hwaddr.sa_data[1],
            ifreq.ifr_hwaddr.sa_data[2],
            ifreq.ifr_hwaddr.sa_data[3],
            ifreq.ifr_hwaddr.sa_data[4],
            ifreq.ifr_hwaddr.sa_data[5]);

  提取到mac中,但是原本Mac地址为 48:4d:7e:b1:e2:7e 存在结果字符输出 48:4D:7E:FFFFFFB1:FFFFFFE2:7E 。这明显不正常,如果使用如下的方式获取则没有问题

unsigned char mac[6];memcpy(mac, ifr.ifr_hwaddr.sa_data, sizeof(mac));
sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X",
             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

  当时考虑到是否是因为不同Linux内核中的结构体 struct ifreq ifr; 中存在差异才导致问题,后来查找到.ifr_hwaddr.sa_data原型为char sa_data[14]。经过相关搜索,问题的原因如下:

  有符号char型的数值范围是-128-127因此大于0x7F的数在char型下其符号位则为1,因此当以%X格式化输出的时候,会把这个类型的值拓展,通常拓展到int型的32位,那么会对char类型的最高位进行拓展,%x期望的数据类型应该是unsigned int型,因此char转换到unsigned int也会拓展符号位,也就是强制类型转换了。

  当为char类型的时候,如果最高位是1,意思是超过了0x7F的数则会被拓展为32位的FFFFFFB1。所以会出现这种情况。但是第二种方法则是直接指定从指针指向的值提取,因此不会出现这种带有符号位的情况。即,使用%x格式化输出的时候,一般char数据会被拓展到int型大小,一般为32位。

  可以通过(unsigned char)ifreq.ifr_hwaddr.sa_data[5]来解决问题。使用%x输出格式的时候需要将所需要的数据转换为无符号类型,因为%x期望对应的参数应该为unsigned int型。

时间: 2024-08-28 09:43:21

关于char型与unsigned char型数据使用格式化输出注意点的相关文章

java如何把char型数据转换成int型数据(转)

一字符串,String=“2324234535”:把第i个数取出来时是char型的:char temp=String.charAt(i)如何把char型转换成int型?我需要求个尾数之和,如:123的各位数之和为6. 每个字符取出来,得到char型的1,2,3,4,5:但是求和得到的结果是ASCII码值 处理办法: (1)把char转成字符串, Integer.parseInt(""+'1')或String a = "12345";int d = Integer.p

char、signed char、unsigned char的区别

ANSI C 提供了3种字符类型,分别是char.signed char.unsigned char char相当于signed char或者unsigned char,但是这取决于编译器! 这三种字符类型都是按照1个字节存储的,可以保存256个不同的值. 不同的是取值范围signed char取值范围是 -128 到 127unsigned char 取值范围是 0 到 255 signed char的最高位为符号位,因此char能表示-128~127, unsigned char没有符号位,

一道int和unsigned char之间强制类型转换的题目

设有语句: ``` int a=258,b; unsigned char c; b=c=a; ``` 则b的值为___. (答案:2) (一)int 类型和char类型之间强制类型转换的规则 ```将int类型变量i的值赋给char类型变量c,会将i的值当作一个ascii码赋给c. int a=51; char c=a; cout<<c<<endl; ``` 输出结果是3 ```将char类型变量c的值赋给int类型变量i,会将c中存储的字符的ascii码当作一个整型数赋给i. c

图像处理中像素点的问题:unsigned char 和 char

以前在做图像处理的时候,一直不太在意这个问题,对图像每个像素点的灰度值,总是认为char也可,unsigned char也可.尽管它们都是8位,但是表示的数的范围却不相同:char: -128~127, unsigned char: 0~255.很明显,unsigned char才是正确的选择. 你可以这样定义: 1 struct { 2     char r; 3     char g; 4     char b; 5 }pixel_t; 6 也可以这样定义: 8 struct { 9    

char 与 unsigned char之间的坑

在C中,默认的基础数据类型均为signed,现在我们以char为例,说明(signed) char与unsigned char之间的区别 首先在内存中,char与unsigned char没有什么不同,都是一个字节,唯一的区别是,char的最高位为符号位,因此char能表示-128~127, unsigned char没有符号位,因此能表示0~255,这个好理解,8个bit,最多256种情况,因此无论如何都能表示256个数字. 在实际使用过程种有什么区别呢? 主要是符号位,但是在普通的赋值,读写

用unsigned char 表示字节

在C中,默认的基础数据类型均为signed,现在我们以char为例,说明(signed) char与unsigned char之间的区别 首先在内存中,char与unsigned char没有什么不同,都是一个字节,唯一的区别是,char的最高位为符号位,因此char能表示-128~127, unsigned char没有符号位,因此能表示0~255,这个好理解,8个bit,最多256种情况,因此无论如何都能表示256个数字. 在实际使用过程种有什么区别呢? 主要是符号位,但是在普通的赋值,读写

[C知识点]char unsigned char signed char知识点

1.char,unsigned char, signed char 都是占一个字节. 2.signed char范围为 -128-127  0000 0000表示+0 1000 0000表示-0.+0和-0表示的值是一样的.为了不浪费这一位用1000 0000表示128 unsigned char范围为 0-256. 3. char根据编译器的不同,被解释成signed char或者unsigned char. 4.VC编译器.x86上的GCC都把char定义为signed char,而arm-

C++ unsigned long 转化为 unsigned char*

C++ Code 123456789101112131415161718   unsigned long lFileLen = 1000; unsigned char *ucFileLenFlag; ucFileLenFlag = (unsigned char *) &lFileLen; //方法一 //方法二: ucFileLenFlag = new unsigned char [4];//数组指针 ucFileLenFlag[3] = ((unsigned char *)&lFileL

strcpy unsigned char

http://bbs.csdn.net/topics/250068243 char *strcpy(char* dest, const char *src); 用unsigned char编译会出错 U8 dest[5]; U8 src[5] = {0x01,0x02,0x03,0x04,0x05}; //加上强制转换 strcpy((char*)dest, (char*)src); 或者使用 void *memcpy(void *dest, const void *src, size_t n)