从 char* 缓冲区读取 int32_t 的惯用 cpp14 方法是什么?
What is the idiomatic cpp14 way to read an int32_t from a char* buffer?
给定一个包含 int(小端)的 char 缓冲区 c。
如何读作 int32_t?
我写了这段代码,但感觉不符合 cpp 的习惯。
int32_t v;
char* p = (char*)&v;
for (int i=0; i < 4; i++) {
*(p+i) = *(c+i);
}
如果您想以便携且安全的方式解决您的问题,请使用 memcpy
作为 。否则,这里有一个更危险的技巧:
请注意,这是 UB。只有在您完全确定缓冲区包含正确数量的数据时才使用下面的技术并且缓冲区和数据正确对齐。
如果您确定系统的字节顺序与 char*
缓冲区中存储的数据之一相匹配,您可以使用 reinterpret_cast
:
std::int32_t v = *reinterpret_cast<std::int32_t*>(p);
没有符合标准的方式来进行上述转换。有关详细信息,请参阅 。
没有神奇的惯用方法来处理字节顺序 — 字节顺序是一个 I/O 问题。要么使用 htonl()
和 ntohl()
函数(在 every 系统上可用),要么自己解码(就像你正在做的那样)。我建议编写函数来做到这一点(让您的生活更轻松,并且可验证)。
没有发现系统字节顺序的标准函数。然而,给定这样一个函数 bool is_little_endian()
returns 仅在小端系统上为真,你可能会这样做:
std::uint32_t read_from_little_endian(char* buf)
{
std::uint32_t u;
if(is_little_endian())
std::copy(buf, buf + sizeof(u), (char*)&u);
else
std::reverse_copy(buf, buf + sizeof(u), (char*)&u);
return u;
}
重要的一点是始终将您的 std::uint32_t*
转换为 char*
,因为只有 char*
可以合法地 别名 所有其他类型。
将 binary 数据从 char*
缓冲区复制到任何其他数据类型的唯一可移植方法是使用 memcpy
(或等效的字节复制诸如 std::copy
之类的方法或模仿此行为的您自己的方法之一)。
memcpy(&my_number, my_buffer, sizeof(my_number));
当然,缓冲区应该包含给定数据类型的正确位。如果它起源于内存复制 from 在同一台机器上使用相同的数据,那么字节顺序就不会起作用。否则,您必须按要求的顺序重新排列字节(就地或在临时缓冲区中),或者在整数本身(可能与 htonl 和朋友)中以平台相关的方式交换字节。
给定一个包含 int(小端)的 char 缓冲区 c。 如何读作 int32_t?
我写了这段代码,但感觉不符合 cpp 的习惯。
int32_t v;
char* p = (char*)&v;
for (int i=0; i < 4; i++) {
*(p+i) = *(c+i);
}
如果您想以便携且安全的方式解决您的问题,请使用 memcpy
作为
请注意,这是 UB。只有在您完全确定缓冲区包含正确数量的数据时才使用下面的技术并且缓冲区和数据正确对齐。
如果您确定系统的字节顺序与 char*
缓冲区中存储的数据之一相匹配,您可以使用 reinterpret_cast
:
std::int32_t v = *reinterpret_cast<std::int32_t*>(p);
没有符合标准的方式来进行上述转换。有关详细信息,请参阅
没有神奇的惯用方法来处理字节顺序 — 字节顺序是一个 I/O 问题。要么使用 htonl()
和 ntohl()
函数(在 every 系统上可用),要么自己解码(就像你正在做的那样)。我建议编写函数来做到这一点(让您的生活更轻松,并且可验证)。
没有发现系统字节顺序的标准函数。然而,给定这样一个函数 bool is_little_endian()
returns 仅在小端系统上为真,你可能会这样做:
std::uint32_t read_from_little_endian(char* buf)
{
std::uint32_t u;
if(is_little_endian())
std::copy(buf, buf + sizeof(u), (char*)&u);
else
std::reverse_copy(buf, buf + sizeof(u), (char*)&u);
return u;
}
重要的一点是始终将您的 std::uint32_t*
转换为 char*
,因为只有 char*
可以合法地 别名 所有其他类型。
将 binary 数据从 char*
缓冲区复制到任何其他数据类型的唯一可移植方法是使用 memcpy
(或等效的字节复制诸如 std::copy
之类的方法或模仿此行为的您自己的方法之一)。
memcpy(&my_number, my_buffer, sizeof(my_number));
当然,缓冲区应该包含给定数据类型的正确位。如果它起源于内存复制 from 在同一台机器上使用相同的数据,那么字节顺序就不会起作用。否则,您必须按要求的顺序重新排列字节(就地或在临时缓冲区中),或者在整数本身(可能与 htonl 和朋友)中以平台相关的方式交换字节。