简体   繁体   English

如何在C中将char [2]转换为无符号的short?

[英]How to convert a char[2] to a unsigned short in C?

I'm having a problem converting data. 我在转换数据时遇到问题。

I got a certain string (which actually represents just some bits of data (little endian), not a text): 我得到了一个特定的字符串(实际上只表示数据的一些位(小端),而不是文本):

char freeBlockSize[2];

and I want to convert it into this type: 我想将其转换为这种类型:

unsigned short numOfBlocks;

I've been trying the following code, but it seems to print garbage, as everytime I run it I got a different output for the value of "numOFBlocks" (freeBlockSize is given to me by another function, and is always the same): 我一直在尝试下面的代码,但它似乎会打印垃圾,因为每次运行它时,我都会为“ numOFBlocks”的值得到不同的输出(freeBlockSize由另一个函数提供给我,并且始终相同):

unsigned short numOFBlocks = (unsigned short)freeBlockSize;

printf("Test: %d %d\n",freeBlockSize[0],freeBlockSize[1]);
printf("Value: %hu\n",numOFBlocks);

Thank you in advance for your help. 预先感谢您的帮助。

Use: 采用:

  unsigned short numOFBlocks = *(unsigned short *)freeBlockSize;

But be careful: this will work if the endianess of the data you have in freeBlockSize is the same endianess of your machine, which could or could not be the case, depending on the source of the data stored in that vector. 但请注意:如果freeBlockSize中的数据的字节序与计算机的字节序相同( freeBlockSize是否存在该freeBlockSize ),这将起作用。


UPDATE: There's a certain risk of accessing a misaligned pointer using this approach, so here you have another method that circunvent this issue: 更新:使用这种方法存在访问未对齐指针的一定风险,因此,这里有另一种方法可以解决此问题:

unsigned short numOfBlocks = ((freeBlockSize[1] << 8) &0xFF00) | (freeBlockSize[0] & 0xFF);

This will take the 16-bit number pointed by freeBlockSize as a LE number, and will store it into numOfBlocks, in host endian format. 这会将freeBlockSize指向的16位数字作为LE数,并将其以主机字节序格式存储到numOfBlocks中。 The previous method wasn't take the host endian into account, and therefore it only worked if the data stored in freeBlockSize was in the same format as host data. 以前的方法没有考虑主机的字节序,因此只有在以freeBlockSize存储的数据与主机数据的格式相同时,它才起作用。

If you want to be able to access the same memory as different values, a union would work. 如果您希望能够以不同的值访问相同的内存,则可以使用union

union short_bytes {
    unsigned short shorty;
    char bytes[2];
};
...
union short_bytes foo;

foo.shorty = (unsigned short)freeBlockSize;

printf("Test: %hhd %hhd\n", foo.bytes[0], foo.bytes[1]);
printf("Value: %hu\n", foo.shorty);

After having a similar problem, I've discovered that char is a signed type. 遇到类似的问题后,我发现char是带符号的类型。 So to use a char type as numbers declare your variable or array as "unsigned char" then when you cast it to a longer type such as unsigned short, it will cast properly. 因此,要将char类型用作数字,请将变量或数组声明为“ unsigned char”,然后将其转换为较长的类型(如unsigned short)时,它将正确进行转换。

Let the compiler optimization take care of the details. 让编译器优化处理细节。

// OP says little endian.
#include <limits.h>
numOfBlocks = (unsigned char) freeBlockSize[1];
numOfBlocks <<= CHAR_BIT;  // thanks @Dietrich Epp 
numOfBlocks += (unsigned char) freeBlockSize[0];

Since OP now says little endian (which match network order) and endian-ness and portability is of concern, consider using after `*(unsigned short *)freeBlockSize``: 由于OP现在说的是很少的endian(与网络顺序匹配),而endian-ness和可移植性值得关注,因此请考虑在`*(unsigned short *)freeBlockSize``之后使用:

#include <netinet/in.h>
uint16_t htons(uint16_t hostshort);
uint16_t ntohs(uint16_t netshort);

Endianess issues aside, it's as simple as reinterpreting the memory holding the char[] array as holding a short : 除了Endianess问题外,它就像重新解释持有char[]数组的内存就像持有short

char freeBlockSize[2];
unsigned short res;
// ..code..
res=*(unsigned short *)freeBlockSize;

By the way, assuming you're using some function and passing in the char[2] as a field inside a structure, you can just define the structure on your side as having the field an unsigned short instead (or an union of the two if you really need the 2 bytes explicitly). 顺便说一句,假设您正在使用某些函数并将char[2]作为结构中的字段传入,则可以将您的结构定义为字段unsigned short (或者两者的并集)如果您确实确实需要2个字节)。 This would let you avoid the extra step. 这样可以避免执行额外的步骤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM