使用 C++ 将四个字节转换为整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34943835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert four bytes to Integer using C++
提问by Y. Franco
I am trying to convert 4 bytes to an integer using C++.
我正在尝试使用 C++ 将 4 个字节转换为整数。
This is my code:
这是我的代码:
int buffToInteger(char * buffer)
{
int a = (int)(buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]);
return a;
}
The code above works in almost all cases, for example:
When my buffer is: "[\x00, \x00, \x40, \x00]"
the code will return 16384
as expected.
上面的代码几乎适用于所有情况,例如:当我的缓冲区为:"[\x00, \x00, \x40, \x00]"
代码将按16384
预期返回。
But when the buffer is filled with: "[\x00, \x00, \x3e, \xe3]"
, the code won't work as expected and will return "ffffffe1"
.
但是当缓冲区充满: 时"[\x00, \x00, \x3e, \xe3]"
,代码将不会按预期工作并返回"ffffffe1"
。
Does anyone know why this happens?
有谁知道为什么会这样?
回答by mindriot
Your buffer
contains signedcharacters. So, actually, buffer[0] == -29
, which upon conversion to int
gets sign-extended to 0xffffffe3
, and in turn (0x3e << 8) | 0xffffffe3 == 0xffffffe3
.
您的buffer
包含签名字符。所以,实际上,buffer[0] == -29
, 在转换为 时int
被符号扩展为0xffffffe3
,反过来(0x3e << 8) | 0xffffffe3 == 0xffffffe3
。
You need ensure your individual buffer
bytes are interpreted unsigned
, either by declaring buffer
as unsigned char *
, or by explicitly casting:
您需要通过声明为或显式转换来确保buffer
解释您的各个字节:unsigned
buffer
unsigned char *
int a = int((unsigned char)(buffer[0]) << 24 |
(unsigned char)(buffer[1]) << 16 |
(unsigned char)(buffer[2]) << 8 |
(unsigned char)(buffer[3]));
回答by Bo Persson
In the expression buffer[0] << 24
the value 24 is an int
, so buffer[0]
will also be converted to an int
before the shift is performed.
在表达式中buffer[0] << 24
,值 24 是 an int
,因此在执行移位之前buffer[0]
也将转换为 an int
。
On your system a char
is apparently signed, and will then be sign extended when converted to int
.
在您的系统上 achar
显然已签名,然后在转换为int
.
回答by Persixty
There's a implict promotion to a signed int in your shifts. That's because char is (apparently) signed on your platform (the common thing) and << promotes to integers implicitly. In fact none of this would work otherwise because << 8 (and higher) would scrub all your bits!
在您的班次中有对签名整数的暗示提升。那是因为 char (显然)在您的平台上签名(常见的事情)并且 << 隐式提升为整数。事实上,这一切都不会起作用,因为 << 8(和更高)会擦掉你所有的东西!
If you're stuck with using a buffer of signed chars this will give you what you want:
如果您坚持使用带符号字符的缓冲区,这将为您提供您想要的:
#include <iostream>
#include <iomanip>
int buffToInteger(char * buffer)
{
int a = static_cast<int>(static_cast<unsigned char>(buffer[0]) << 24 |
static_cast<unsigned char>(buffer[1]) << 16 |
static_cast<unsigned char>(buffer[2]) << 8 |
static_cast<unsigned char>(buffer[3]));
return a;
}
int main(void) {
char buff[4]={0x0,0x0,0x3e,static_cast<char>(0xe3)};
int a=buffToInteger(buff);
std::cout<<std::hex<<a<<std::endl;
// your code goes here
return 0;
}
Be careful about bit shifting on signed values. Promotions don't just add bytes but may convert values.
小心对有符号值进行位移。促销不仅会增加字节,还可能会转换值。
For example a gotcha here is that you can't use static_cast<unsigned int>(buffer[1])
(etc.) directly because that converts the signed char value to a signed int and then reinterprets that value as an unsigned.
例如,这里的一个问题是您不能static_cast<unsigned int>(buffer[1])
直接使用(等),因为这会将有符号的 char 值转换为有符号的 int,然后将该值重新解释为无符号。
If anyone asks me all implicit numeric conversions are bad. No program should have so many that they would become a chore. It's a softness in the C++ inherited from C that causes all sorts of problems that far exceed their value. It's even worse in C++ because they make the already confusing overloading rules even more confusing.
如果有人问我所有隐式数字转换都是不好的。任何程序都不应该有这么多,以至于它们会成为一件苦差事。正是从 C 继承的 C++ 中的一种软性导致了远远超出其价值的各种问题。在 C++ 中情况更糟,因为它们使已经令人困惑的重载规则更加令人困惑。