简体   繁体   English

C++,将整数字节打包成一个字符数组?

[英]C++, pack integer bytes into a char array?

I'm transferring data over network, so trying to set up a header, where first 3 bytes are a message type, and the next 4 bytes are the size of the message.我正在通过网络传输数据,因此尝试设置一个标头,其中前 3 个字节是消息类型,接下来的 4 个字节是消息的大小。 When I'm adding an integer, for anything over 127 bytes, I'm overflowing.当我添加一个整数时,对于超过 127 个字节的任何内容,我都溢出了。 How do I set up such header?我如何设置这样的标题?

Here's a simple example.这是一个简单的例子。 If num is 127 or less, then the output is correct, but if it's 128 or more, then the output is all messed up.如果 num 为 127 或更少,则输出是正确的,但如果 num 为 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;
}

If num is 127 or less, then the output is correct, but if it's 128 or more, then the output is all messed up.如果 num 为 127 或更少,则输出是正确的,但如果 num 为 128 或更多,则输出完全混乱。

It appears you're talking about the following part of the code where you try to read your integer back out of the char array and then display it:看来您正在谈论代码的以下部分,您尝试从 char 数组中读取整数然后显示它:

int out = *(x + 3);
cout << "out: " << out << endl;

The problem is that x + 3 is of type char* , and when you dereference that it becomes a char value.问题是x + 3char*类型,当您取消引用它时,它变成了一个char值。 On your system, that value is signed and integers are obviously stored in little-endian form.在您的系统上,该值是有符号的,整数显然是以小端格式存储的。 So, you think it "works" for values less than 128. But actually that's not even true.所以,你认为它对小于 128 的值“有效”。但实际上这甚至不是真的。 It will also break for values less than -128.对于小于 -128 的值,它也会中断。

You see, even though you're assigning this to a int , it's still only a char .你看,即使你把它分配给一个int ,它仍然只是一个char That char value is simply being copied into a larger integer type.该 char 值只是被复制到更大的整数类型中。

It looks like you actually wanted this:看起来你真的想要这个:

int out = *(int*)(x + 3);  // DON'T DO THIS!

This is called type punning (treating some memory as if it contained another type) and should be avoided !!!这称为类型双关(将某些内存视为包含另一种类型),应该避免!!!

Instead, you should just copy the bytes out the same way you copied them in:相反,您应该像复制字节一样复制字节:

int out;
memcpy(&out, x + 3, sizeof(out));

Also beware that if you plan to transfer binary data over a network, that any machine reading this data must be aware of its endianness .另请注意,如果您计划通过网络传输二进制数据,则任何读取此数据的机器都必须了解其字节序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM