【问题标题】:How to read integer from a char buffer into an int variable如何将 char 缓冲区中的整数读入 int 变量
【发布时间】:2021-05-04 12:48:32
【问题描述】:

我是 c 编程的新手,并且正在使用套接字编程。我想将 char* 缓冲区中的值存储到不同的变量中,但我在存储 int 值时遇到了麻烦。

我从套接字接收到的数据是二进制的,并使用recv() 保存在char* buffer 中。 缓冲区的前 3 个字节将保存在三个不同的 unsigned char 变量中,这样做可以正常工作:

unsigned char first = buffer[0];
unsigned char second= buffer[1];
unsigned char third = buffer[2];

现在我的问题出现了。我想将下一个字节保存在两个 int 变量中(每个 4 个字节)。现在我试过了:

unsigned int fourth= buffer[3];
unsigned int fifth= buffer[7];

第四个变量保存数字 83,这是预期的。 但是,第五个变量应该是数字 1000,但我得到的是 232。我在这里缺少什么?

【问题讨论】:

  • 至少在你的问题中显示字符缓冲区的内容,
  • 您是否已经了解了多字节值?您需要根据二进制数据的字节序来计算整数。
  • 我猜这已经是answered here了。但是当 OP 询问他为什么得到 232 而不是 1000 时:unsigned int fifth= buffer[7]; 表示将 char 值(一个字节)从 buffer[7] 分配给堆栈上的变量 fifth。由于十进制 1000 是十六进制的 0x3E8,并且数据以 little endian 方式存储,因此 buffer[7] 中的 0xE8(十进制 232)和 buffer[8] 中的 0x3,buffer[9]buffer[10] 中的 0x0。
  • unsigned int fifth= buffer[7]; 不从buffer[7..10] 中获取四个字节,它只获取buffer[7] 的值并将其作为int 存储到fifth 中。请参阅链接的问题以了解如何获取您的 int 值。
  • "正在使用套接字编程" 那么使用的协议的网络字节序和客户端的 CPU 字节序是什么?

标签: c


【解决方案1】:

你有三种方式:

unsigned int fourth
unsigned int fifth;
  1. 如果字节序相同
memcpy(&fourth, &buffer[3], sizeof(fourth));
memcpy(&fifth, &buffer[7], sizeof(fifth));

或者你可以使用联合。

  1. 更通用的方式(但您仍然需要知道数据是如何存储在缓冲区中的)

如果缓冲区首先存储最不重要的字节(小端):

fourth = buffer[3] + (((unsigned int)buffer[4]) << 8) + (((unsigned int)buffer[5]) << 16) + (((unsigned int)buffer[6]) << 24)

如果缓冲区最后存储最不重要的字节(大端):

fourth = buffer[6] + (((unsigned int)buffer[5]) << 8) + (((unsigned int)buffer[4]) << 16) + (((unsigned int)buffer[3]) << 24)

【讨论】:

    【解决方案2】:

    我在这里错过了什么?

    您错过了unsigned int fourth= buffer[3]; 只会读取您想要的 4 个字节中的 1 个。要获得正确的值,您需要阅读并使用buffer[3]buffer[4]buffer[5]buffer[6]。为了获得整数值,您需要应用适当的位移并将事物相加。

    当数据通过网络交换时,数据(也应该总是)以“网络顺序”发送。主机可以使用不同的字节顺序。所以先将这4个字节转换为“网络顺序”的无符号32位整数,然后再转换为主机顺序。

    uint32_t network_uint32 = ((unsigned int)buffer[3] << 24) +
                              ((unsigned int)buffer[4] << 16) +
                              ((unsigned int)buffer[5] <<  8) +
                               (unsigned int)buffer[6];
    uint32_t host_uint32 = ntohl(network_uint32);
    

    通过这种方式,您的代码可以在小端主机和大端主机上运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 2012-05-27
      • 1970-01-01
      相关资源
      最近更新 更多