【问题标题】:C hexadecimal convert to a char pointerC 十六进制转换为 char 指针
【发布时间】:2018-11-07 02:47:16
【问题描述】:

所以我有一段代码基本上应该将 u_int32(或十六进制)中给出的 IP 地址的第一个字节转换为 char*。例如,给定一个 192.168.10.49 (0x31 0x0a 0xa8 0xc0),应该返回 192 (0xc0)。 IP 地址以网络字节顺序给出。我写了一段代码,但是我不明白它是如何以及为什么这样工作的。

struct sockaddr_in *addr = (struct sockaddr_in *) malloc(sizeof(addr));
unsigned char *ip_str;
int i = 0;

/* cast sockaddr to sockaddr_in. ip is given as an argument of sockaddr */
addr = (struct sockaddr_in*) ip;

/* cast address */
ip_str = (char *) &(addr->sin_addr.s_addr);

printf("addr: %02x\n", addr->sin_addr.s_addr);
printf("ip_str: %02x\n", (int) (*ip_str));

在这段代码中,我给出了一个 sockaddr 结构,其中包含网络字节顺序的 IP 地址,然后我将其转换为 sockaddr_in 结构。最后,我将 u_int32 格式的 IP 地址转换为 char 指针并得到 192 的结果(假设 ip 为 192.168.10.49)。首先 printf 函数以十六进制打印 IP,其输出为:

310aa8c0

第二个,结果,打印为:

c0

但是,如果我从网络字节顺序转换为主机字节顺序(使用 ntohl()),我会得到以下结果:

c0a80a31

第二个打印出来:

31

我的问题是,这个演员阵容是如何工作的?为什么它会投射到 IP 地址的最后一个字节?欢迎任何指向有关此教程或参考书籍的教程的链接。

【问题讨论】:

  • ip 没有在代码中定义
  • 不需要为addr动态分配内存。特别是因为您随后重新分配 addr 导致内存泄漏,并且当您稍后尝试将该指针传递给 free 时可能出现未定义的行为。
  • 至于你的问题,在我看来你需要了解整数如何工作或存储在计算机中,以及关于endianness。参加有关基本计算机体系结构的课程,或者至少找到有关它的教程或教科书。
  • @Someprogrammerdude 好的,关于内存泄漏的提示,不知道。我会研究字节序
  • @aretas_pau 我明白这是什么意思,但一般来说,当您发布minimal reproducible example

标签: c networking casting ip hex


【解决方案1】:

网络字节顺序是大端,显然您的主机字节顺序是小端。因此,使用ntohl 反转字节串。

注意在

printf("ip_str: %02x\n", (int) (*ip_str));

ip_str 是指向unsigned char 的指针。取消引用它会返回ip_str 中的第一个字节。

现在,您想知道为什么输出第一个而不是最后一个字节。这正是因为字节顺序。在内存中,您的四字节 ip_str 采用 little-endian 格式,即最低有效字节存储为第一个。因此,如果您访问的不是整个四字节字符串,而是仅访问第一个字节,实际上您访问的是最后一个字节。

【讨论】:

  • 所以,据我了解,这一切都归结为计算机如何将其字节存储在内存中?
  • @aretas_pau 没错。您所做的是实现定义的,因为不同的计算机具有不同的字节序设置。
  • 至于可移植性,我想这样的实现很糟糕?
  • @aretas_pau 这就像你从我嘴里说出来的话。不明确,不便携,正确。
  • 好的,谢谢您的解释。我将尝试使其更便携和定义明确。似乎有很多有趣的东西可以学习
猜你喜欢
  • 2011-05-25
  • 2022-12-20
  • 2012-02-24
  • 2013-05-07
  • 2013-06-07
  • 2013-09-01
  • 2018-11-18
  • 2013-01-11
  • 2017-07-31
相关资源
最近更新 更多