首页 > 解决方案 > C++ 无法转换矢量到 int

问题描述

我正在使用 boost ASIO 通过 TCP 流发送消息。我首先以严格的 4 字节长度发送正文大小。比在服务器端我制作了一个vector<char>我调整为 4 个字节的大小,并将消息正文大小放在那里。这是我如何将 char 向量转换std::vector<char> size;为 int 的方法:

_packet.body_size = static_cast<int>(_packet.size[0]);

_packet.size[0]当保存在内部的值不大于 124时,此方案有效。

在此处输入图像描述

在这种情况下有效。如您所见,body_size设置为。124

但是,如果该值变得大于124例如128我无法正确解析它,就像我对124.

看一看:

在此处输入图像描述

看看设置的数字是多少body_size。为什么我不能转换大于 124 的数字?

错误在哪里,我该如何解决?

标签: c++

解决方案


要从char向量中的 4 个单字节值构造一个(4 字节/32 位)整数,并安全地这样做,您需要将每个字符“屏蔽”到该整数的相关 8 位中。

您可以在一个短循环中使用按位或 ( |) 和位移 ( ) 操作的组合来执行此操作:<<

#include <iostream>
#include <vector>

int main()
{
    std::vector<char> cVec = { -128, 0, 0, 0 };
    int32_t iVal = 0;
    for (size_t i = 0; i < 4; ++i) {
        iVal |= static_cast<int>(cVec[i]) << (i * 8);
    }
    std::cout << iVal << std::endl;
    return 0;
}

以上将适用于对整数使用Little-Endian 字节序列的系统(最常见的处理器,如 Intel x86/x64 系列,使用此系统)。在 Big-Endian 系统上,您需要以相反的顺序添加字节,使用以下作为for循环的“主体”:

        iVal |= static_cast<int>(cVec[3-i]) << (i * 8);

注意:将向量数据的地址转换为指向 int 的指针然后取消引用它可能很诱人(正如我在评论中建议的那样)。但是,这是不安全的,并且会引入未定义的行为,因为它违反了 C++ 语言的严格别名规则


推荐阅读