c++ - C++,将整数字节打包成一个字符数组?
问题描述
我正在通过网络传输数据,因此尝试设置一个标头,其中前 3 个字节是消息类型,接下来的 4 个字节是消息的大小。当我添加一个整数时,对于超过 127 个字节的任何内容,我都会溢出。如何设置这样的标题?
这是一个简单的例子。如果 num 为 127 或更少,则输出正确,但如果为 128 或更多,则输出全部混乱。
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
string bytesAsStr(char* src, int size)
{
stringstream ss;
ss << std::hex;
for (int i = 0; i < size; i++)
{
ss << std::setw(2) << std::setfill('0') << (int)src[i] << " ";
}
return ss.str();
}
int main()
{
// 3 chars + 1 int
const int size = 3 + sizeof(int);
char x[size];
memcpy(x, "lsa", 3);
int num = 129;
memcpy(x + 3, &num, sizeof(int));
cout << bytesAsStr(x, size) << endl;
int out = *(x + 3);
cout << "out: " << out << endl;
}
解决方案
如果 num 为 127 或更少,则输出正确,但如果为 128 或更多,则输出全部混乱。
看来您正在谈论代码的以下部分,您尝试从 char 数组中读取整数然后显示它:
int out = *(x + 3);
cout << "out: " << out << endl;
问题在于它x + 3
是 type char*
,当你取消引用它时它变成了一个char
值。在您的系统上,该值是有符号的,并且整数显然是以小端形式存储的。所以,你认为它对小于 128 的值“有效”。但实际上这甚至不是真的。对于小于 -128 的值,它也会中断。
你看,即使你将它分配给 a int
,它仍然只是 a char
。该 char 值只是被复制到更大的整数类型中。
看起来你实际上想要这个:
int out = *(int*)(x + 3); // DON'T DO THIS!
这称为类型双关语(将某些内存视为包含另一种类型)并且应该避免!
相反,您应该像复制它们一样复制字节:
int out;
memcpy(&out, x + 3, sizeof(out));
另请注意,如果您计划通过网络传输二进制数据,则任何读取此数据的机器都必须知道其字节顺序。
推荐阅读
- python - Twitter API NameError Python 社交媒体分析
- php - 如何获取文本输入并将其粘贴到使用 PHP 的链接前面?
- keyboard - MacOS中方向按键的意外输出
- exception - 在 ASP.NET Core 2.2 上运行的中间件中是否有任何方法可以检测请求是否针对 ApiController?
- recurrent-neural-network - 为什么在反向传播中随着时间的推移添加梯度而不是平均?
- c# - 限制并发异步任务
- wordpress - 静态页面到动态wordpress
- sql-server - SSRS 报表生成器运行我在 SSMS 中找不到的程序
- php - 登录管理面板后如何修复WordPress白屏?
- docker - 什么是使用 kubernetes pod 挂载文件夹?