【问题标题】:C++ | Convert int to byte[4] and vice versaC++ |将 int 转换为 byte[4],反之亦然
【发布时间】:2016-11-03 11:58:45
【问题描述】:

我正在尝试将整数转换为字节(又名无符号字符)数组,以通过 C++ 中的 TCP 流发送数组,反之亦然。

我在 stackoverflow 和自己的想法上尝试了许多解决方案,但似乎没有什么真正适合我。

我的最后一个解决方案是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include "tcpconnector.h"

typedef unsigned char byte;

using namespace std;

/*
char* byteToChar(byte* b, int length) {
    char c[length];
    for (int i = 0; i < length; i++) {
    c[i] = b[i] - 128;
    }
    return c;
}

byte* charToByte(char* c, int length) {
    byte b[length];
    for (int i = 0; i < length; i++) {
    b[i] = c[i] + 128;
    }
    return b;
}
*/

byte* intToByte(int n) {

    byte byte[4];

     byte[0] = n & 0x000000ff;
     byte[1] = n & 0x0000ff00 >> 8;
     byte[2] = n & 0x00ff0000 >> 16;
     byte[3] = n & 0xff000000 >> 24; 

     return byte;
}

int byteToInt(byte* byte) {

    int n = 0;

    n = n + (byte[0] & 0x000000ff);
    n = n + ((byte[1] & 0x000000ff) << 8);
    n = n + ((byte[2] & 0x000000ff) << 16);
    n = n + ((byte[3] & 0x000000ff) << 24);


    return n;
}

int main(int argc, char** argv)
{
    if (argc != 3) {
        printf("usage: %s <port> <ip>\n", argv[0]);
        exit(1);
    }

    int number = 42;
    byte* line = intToByte(number);

    cout << "Number: " << number << "\n";
    cout << "ArrayLength: " << sizeof line << "\n";
    cout << "Array: " << line << "\n";
    cout << "Array to Number: " << byteToInt(line) << "\n";

/*

    TCPConnector* connector = new TCPConnector();
    TCPStream* stream = connector->connect(argv[2], atoi(argv[1]));
    if (stream) {
        stream->send(byteToChar(line, 4), 4);
        delete stream;
    }

*/
    exit(0);
}

每次执行此代码时,无论我设置什么“int number”,我都会得到结果“4202308”。

任何帮助将不胜感激。

更新:

void intToByte(int n, byte* result) {

     result[0] = n & 0x000000ff;
     result[1] = n & 0x0000ff00 >> 8;
     result[2] = n & 0x00ff0000 >> 16;
     result[3] = n & 0xff000000 >> 24; 
}

摘自 main():

int number = 42;
byte line[4];
intToByte(number, line);

cout << "Number: " << number << "\n";
cout << "ArrayLength: " << sizeof line << "\n";
cout << "Array: " << line << "\n";
cout << "Array to Number: " << byteToInt(line) << "\n";

【问题讨论】:

  • 你确定你机器的字节顺序了吗?
  • 很难判断代码中缺少的 cmets 何时不显示结果数组应该存在的位置 - 要么提供其地址/对它的引用作为参数,要么动态分配它。考虑更改函数的名称 - 至少更改为 …Bytes…()
  • 在这种情况下,这应该没有问题,因为我在同一台机器上来回移动相同的字节。但是一旦我通过 TCP 流传输数据,这可能会出现问题。

标签: c++ arrays integer byte endianness


【解决方案1】:

您的intToByte 函数在其主体范围内分配byte[4],然后返回指向它的指针。

因此,一旦您的函数返回,该值就会被丢弃,并且调用者收到的只是一个指向现在无效位置的指针 - 值在超出范围时被销毁,并且指针不会延长该生命周期。

要么使用标准容器对象,例如 std::arraystd::vector,您的函数应将其返回给调用者,或者让 intToByte 接受 byte[4]/byte* 作为参数并填写它。

为了完整性...您还可以让函数使用new 创建字节数组,但是您必须记住delete[] 它,虽然在这种情况下看起来很容易,当您没有充分的理由进行动态分配时,这通常是一种不好的做法。

此外,语句x &amp; y &gt;&gt; z 将首先执行y &gt;&gt; z然后 按位-与x 的结果,这当然不是你想要的。

【讨论】:

  • 非常感谢!这是有道理的,我现在记得你必须通过参数传递引用。这也可以解释为什么 sizeof 行总是返回 8 而不是 4
  • 我认为你的意思是 通过引用传递参数 - 虽然这在这里不适用,因为一切都是按值传递的,因为虽然指针可以被视为引用,但你真的只是传递指针的值。尽管如此,您也可以接受byte (&amp;)[4] 而不是byte* 作为解决问题的一种方式。虽然如果std::array 是一个选项,请使用它。
  • 遗憾地将签名更改为void intToByte(int n, byte* result) 并填写数组并没有真正帮助。也许我的转换逻辑仍然存在问题。我会尝试使用 std::array 但我想知道为什么将 byte* 作为参数传递也不应该起作用。
  • 你实际上传递给它什么?您应该在调用者中创建一个 byte[4] 并将其传递给 intToByte
  • 我将更改添加为对原始帖子的更新
【解决方案2】:

第一点: 您从byte* intToByte(int n) 返回的缓冲区不安全。 您正在返回本地数组的基地址。要么传递一个字节数组作为输入,要么在堆中分配字节并返回地址

第二点:

考虑运算符优先级。

 byte byte[4];
 byte[0] = n & 0x000000ff;
 byte[1] = ( n & 0x0000ff00 ) >> 8;
 byte[2] = ( n & 0x00ff0000 ) >> 16;
 byte[3] = ( n & 0xff000000 ) >> 24; 

【讨论】:

  • 谢谢!使用结果数组作为参数后,缺少的括号是问题。我怎么没想到
【解决方案3】:

此函数将c++中的所有标准类型转换为字节向量。

template <typename T>
std::vector<byte> ToByte(T input) 
{
    byte* bytePointer = reinterpret_cast<byte*>(&input);
    return std::vector<byte>(bytePointer, bytePointer + sizeof(T));
}

【讨论】:

    【解决方案4】:

    很遗憾,这不是您问题的准确答案,但可能会有所帮助。我认为你可以像下面的代码那样做。

    #include <stdio.h>
    using namespace std;
    
    unsigned char* intToByte(const int& N) {
    
        unsigned char* byte = new unsigned char[4];
    
        byte[0] = (N >> 24) & 0xFF;
        byte[1] = (N >> 16) & 0xFF;
        byte[2] = (N >> 8) & 0xFF;
        byte[3] = N & 0xFF;
    
        return byte;
    }
    
    
    int main()
    {
        unsigned char * result = intToByte(255);
        printf("%x %x %x %x\n", (unsigned char)result[0], (unsigned char)result[1],
                                (unsigned char)result[2], (unsigned char)result[3]);
    
        delete result;
        return 0;
    }
    

    【讨论】:

    • 确实解决了这个问题,但也恰好是我所说的坏事(TM)。虽然我很想知道为什么你认为传递 int&amp; 而不是 int 更好。
    • 它是 const int& 不是 int&
    • 是的,为简洁起见,我省略了它,因为这与我的问题无关,我对你的 const 正确性没有任何疑虑。
    • 质量不是一种行为,而是一种习惯。 :)))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    相关资源
    最近更新 更多