使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:27:34  来源:igfitidea点击:

Convert four bytes to Integer using C++

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 16384as 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 buffercontains signedcharacters. So, actually, buffer[0] == -29, which upon conversion to intgets 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 bufferbytes are interpreted unsigned, either by declaring bufferas unsigned char *, or by explicitly casting:

您需要通过声明为或显式转换来确保buffer解释您的各个字节:unsignedbufferunsigned 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] << 24the value 24 is an int, so buffer[0]will also be converted to an intbefore the shift is performed.

在表达式中buffer[0] << 24,值 24 是 an int,因此在执行移位之前buffer[0]也将转换为 an int

On your system a charis 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++ 中情况更糟,因为它们使已经令人困惑的重载规则更加令人困惑。