我想要做的是将数据存储在std::vector<short>
的{{1}}中,将每个短片分成两个uint8_t值。我需要这样做因为我有一个只发送std::vector<uint8_t>
的网络应用程序,所以我需要转换为uint8_t发送,然后在收到uint8_t向量时转换回来。
通常我会做什么(以及我在查看问题时所看到的)是:
std::vector<uint8_t>
但是,如果我理解正确的话,这将取每个单独的短值,截断到uint8_t的大小,并创建一个新数据量和相同数量的条目的向量,当我想要的是相同的包含两倍条目的数据量。
解决方案包括一种扭转过程并尽可能避免复制的方法,这将有很大帮助。谢谢!
答案 0 :(得分:6)
在8位边界处分割一些东西,你可以使用右移和掩码,即
uint16_t val;
uint8_t low = val & 0xFF;
uint8_t high = (val >> 8) & 0xFF;
现在您可以将您的高点和低点放入订单中的第二个向量中。
答案 1 :(得分:3)
对于拆分和合并,您将拥有以下内容:
unsigned short oldShort;
uint8_t char1 = oldShort & 0xFF; // lower byte
uint8_t char2 = oldShort >> 8; // upper byte
然后将两个部分推到矢量上,并将其发送到您的网络库。在接收端,在重新组装期间,您将读取向量的下两个字节,并将它们组合回短路。
注意:确保接收到的矢量上有偶数个元素,以便在传输过程中不会获得损坏/修改的数据。
// Read off the next two characters and merge them again
unsigned short mergedShort = (char2 << 8) | char1;
答案 2 :(得分:2)
我需要这样做是因为我有网络应用程序 1 只能发送std :: vector&#39;
除了屏蔽和位移之外,您还应该在通过网络发送内容时考虑结束。
network 数据表示通常是 big endian 。所以你总是可以把MSB放在第一位。提供简单的功能,如:
std::vector<uint8_t> networkSerialize(const std::vector<uint16_t>& input) {
std::vector<uint8_t> output;
output.reserve(input.size() * sizeof(uint16_t)); // Pre-allocate for sake of
// performance
for(auto snumber : input) {
output.push_back((snumber & 0xFF00) >> 8); // Extract the MSB
output.push_back((snumber & 0xFF)); // Extract the LSB
}
return output;
}
并像
一样使用它std::vector<uint8_t> newVec = networkSerialize(oldvec);
请参阅live demo。
1) 强调我的
答案 3 :(得分:1)
免责声明:人们在谈论“网络字节顺序”。如果你发送的信息超过1个字节,当然你需要take network endiannes into account。但是,据我所知,限制“仅发送std::vector<uint8_t>
的网络应用程序”明确指出“我不想搞乱那些字节序的东西” 。 uint8_t
已经是一个字节,如果你按一个顺序发送一个字节序列,你应该以完全相同的顺序返回它们。这很有用:sending the array through a socket.
在客户端和服务器计算机上可以有不同的系统字节顺序,但是OP没有说明它,所以这是一个不同的故事......
关于答案:
假设所有“endianness”问题都已关闭。
如果你只想发送一个短裤矢量,我相信, VTT 的答案会表现最佳。但是,如果std::vector<short>
只是一个特例,您可以使用my answer to a similar question中的pack()
函数。它将任何可迭代的容器,字符串,C字符串等包装到一个字节向量中,不执行任何endiannes shenanigans。
只需包含byte_pack.h
然后你可以像这样使用它:
#include "byte_pack.h"
void cout_bytes(const std::vector<std::uint8_t>& bytes)
{
for(unsigned byte : bytes) {
std::cout << "0x" << std::setfill('0') << std::setw(2) << std::hex
<< byte << " ";
}
std::cout << std::endl;
}
int main()
{
std::vector<short> test = { (short) 0xaabb, (short) 0xccdd };
std::vector<std::uint8_t> test_result = pack(test);
cout_bytes(test_result); // -> 0xbb 0xaa 0xdd 0xcc (remember of endianness)
return 0;
}
答案 4 :(得分:-1)
只需一次复制所有内容:
::std::vector<short> shorts;
// populate shorts...
::std::vector<uint8_t> bytes;
::std::size_t const bytes_count(shorts.size() * sizeof(short) / sizeof(uint8_t));
bytes.resize(bytes_count);
::memcpy(bytes.data(), shorts.data(), bytes_count);