在 C++ 中从 size_t 转换/转换为 uint8_t?

Posted

技术标签:

【中文标题】在 C++ 中从 size_t 转换/转换为 uint8_t?【英文标题】:Casting/converting from size_t to uint8_t in C++? 【发布时间】:2011-12-10 13:18:46 【问题描述】:

我正在尝试编写一些代码,使用 boost::asio 的套接字将消息从一端(客户端)发送到另一端(服务器)。

我现在的具体目标是在发送的每条消息前加上一个 1 字节的无符号整数 (uint8_t),告诉接收者消息的其余部分有多少字节。

请注意,我将大小存储和传输为 uint8_t 而不是 size_t 的原因是因为我想确保它在两台机器上都是 1 个字节。谷歌搜索表明 size_t 在机器 A 和机器 B 上的大小可能不同,这可能会搞砸。

所以我在这里计算消息的长度。该消息仅由两部分组成:一个 uint16_t,后跟一个变量“data”,它是一个 (void*)-cast 的内存块,可用于不同的目的(目标机器有解释该数据的方法,但我不会此处不赘述)。

uint8_t sizeOfMessage = sizeof(uint16_t) + sizeof(data);

在本例中,sizeof(data) == 4,因此 sizeOfMessage 应该等于 6(因为 uint16_t 是一个 2 字节整数)。但是,如果我 std::cout 6 '-' 。但是,如果我将 sizeOfMessage 定义为 size_t 并将其打印出来,一切都很好(但当然,我不能通过网络发送它,因为不能保证从一台机器到下一台机器的 size_t 的字节大小)。

我认为这意味着在算术之后如何将 size_t 转换为 uint8_t 出现问题。 sizeof 返回一个 size_t,所以我的代码正在做的是添加两个 size_t,然后将其转换为一个 uint8_t。

我的结论是否正确,即该值未正确转换?如果是这样,我该如何解决?

提前致谢。

【问题讨论】:

【参考方案1】:

uint8_t 在您的系统中是一个 unsigned char,因此输出它时会将其写入为字符而不是整数,即值为 6 的字符。

你的演员没有错。

【讨论】:

【参考方案2】:

uint8_t 通常是 char 类型的 typedef,并且它们被重载以格式化输出以打印为字符,而不是数字。不幸的是,这是 C++ 格式化 I/O 的丑陋方面之一,因为您必须转换为整数才能打印:

char c;
unsigned char u;

std::cout << (unsigned int)(unsigned char)(c) << std::endl
          << (unsigned int)(u) << std::endl;

【讨论】:

而不是(unsigned int)(u),只写u+0(转换为int,这在sizeof(int) > 1的任何架构上都足够好)。好吧,johannes 显然更喜欢写得更简洁,如+u。但我认为这有点令人困惑。 @AlfP.Steinbach:这是一个不错的技巧 :-) 不过,对于未装饰的字符,我想您仍然需要进行符号转换。【参考方案3】:

分配给您的小 (uint8_t) 变量的值不是显示为“6”的可打印 ASCII 字符代码。相反,它是一个二进制值,相当于在您的源代码中编码 '\006'。如果您的数据传输协议确实适用于二进制代码字节,那么您可能很高兴。接收程序在其读取一个字节 (char) 的 (uint8_t) 实例中得到什么?当然,使用 (uint8_t) 会将您的总消息长度限制为 0 到 255(但您知道这一点)。

【讨论】:

感谢所有回答的人,你的原因是正确的:我的机器认为 uint8_t 是一个字符,呵呵。我的端点正在接收消息并将其解释为 0(这是第一个意外行为,并导致我进行调试,这让我提出了这个问题);事实证明,这是因为我需要将我的 write() 分成两个单独的调用.. 或者看起来.. boost::asio 非常令人困惑。 ://

以上是关于在 C++ 中从 size_t 转换/转换为 uint8_t?的主要内容,如果未能解决你的问题,请参考以下文章

错误:在 C++ 中从“Counter”转换为非标量类型“CountDn”

在C++中,如何把字节数组转换成字符串

无法将参数 5 从 'SIZE_T *' 转换为 'size_t *' -- 为啥?

在 C 中从 HEX 颜色转换为 RGB 结构

将字符串转换为 size_t

如何在 Windows 中从任何格式转换为 PCM