如何在C语言中将`int`数组转换为IP地址字符串?
我有一个如何在C语言中将`int`数组转换为IP地址字符串?,c,C,我有一个int数组,它存储一个IP地址: int ipArr[4] = {192,168,1,60} 我需要将上面定义的地址转换为类似于“192.168.1.60”的字符串。我尝试了sprintf和strcat函数,但代码仍然非常繁琐。处理句点标点是非常棘手的。 我的代码如下: char srcIp[16]; int i=0,index=0; for(i=0;i<4;i++){ index+=sprintf(&srcIp[index],"%d",sourceIpInt[i]
int
数组,它存储一个IP地址:
int ipArr[4] = {192,168,1,60}
我需要将上面定义的地址转换为类似于“192.168.1.60”
的字符串。我尝试了sprintf
和strcat
函数,但代码仍然非常繁琐。处理句点标点是非常棘手的。
我的代码如下:
char srcIp[16];
int i=0,index=0;
for(i=0;i<4;i++){
index+=sprintf(&srcIp[index],"%d",sourceIpInt[i]);
if(i<3){
index+=sprintf(&srcIp[index],"%c",'.');
}
}
charsrcip[16];
int i=0,索引=0;
对于(i=0;i而言,使用单个sprintf()
在一次调用中格式化所有ip地址八位字节比在循环中格式化更简单、更容易
如果缓冲区可以是局部变量
char缓冲区[16];
const int ip[4]={172,0,0,1};
sprintf(缓冲区,“%d.%d.%d.%d”,*ip,ip[1],ip[2],ip[3]);
printf(“IP地址为:%s”,缓冲区);
或者,如果您需要使用动态内存,您可以执行以下操作
char*buffer=malloc(16);
const int ip[4]={172,0,0,1};
如果(!缓冲区){
佩罗尔(“马洛克”);
出口(1);
}
sprintf(缓冲区,“%d.%d.%d.%d”,*ip,ip[1],ip[2],ip[3]);
printf(“IP地址为:%s”,缓冲区);
自由(缓冲);
在上面的代码中,我使用动态内存分配来创建缓冲区,并使用sprintf
将数据写入缓冲区
请注意malloc(16)
-sizeof(char)
根据定义等于1
,因此我们不需要编写malloc(sizeof(char)*16)
更好的方法是使用可移植库函数
它将:
- 通过添加对IPv6的支持,使您的代码经得起未来的考验
- 使您的代码与使用IP地址的许多其他函数兼容
例如:
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
void main(){
// IP addresses might be longer on this system eg. see https://stackoverflow.com/questions/55958327/how-to-convert-an-int-array-to-an-ip-address-string-in-c
char str[INET_ADDRSTRLEN];
// this "socket address" is a very portable address format which you will use when dealing with sockets
struct sockaddr_in sa;
// this format is not portable or usable when dealing with other libaries, unless you convert it
// note that technically 'unsigned char' is more accurate, but it will be processed slower than int on modern PC's
unsigned char a_ipv4addr[4] = {192,168,1,60};
// Don't do this! This will only work on little-endian machines, when compiled without certain optimizations - so it's not portable. That's why you should rather use the functions - some day soon you might want your code to run on a RISC V processor...
memcpy(&sa.sin_addr.s_addr,&a_ipv4addr,4);
inet_ntop(AF_INET, &sa.sin_addr, str, INET_ADDRSTRLEN);
printf("Bad example with memcpy: %s\n", str);
// sprintf your address, and then convert it - if you absolutely have to use your format
sprintf(str,"%i.%i.%i.%i",a_ipv4addr[0],a_ipv4addr[1],a_ipv4addr[2],a_ipv4addr[3]);
inet_pton(AF_INET, str, &(sa.sin_addr)); // now you can use it in other functions
inet_ntop(AF_INET, &sa.sin_addr, str, INET_ADDRSTRLEN); // just to show that it's correct
printf("Better example from generated string: %s\n", str);
// you can also represent it as an unsigned int
unsigned int ipv4addr=0x3c01a8c0; // c0.a8.01.3c = 192.168.1.60 backwards aka little-endian
sa.sin_addr.s_addr=ipv4addr;
inet_ntop(AF_INET, &sa.sin_addr, str, INET_ADDRSTRLEN);
printf("Example from unsigned int: %s\n", str);
// you can also represent it as an unsigned int, in decimal
ipv4addr=192+(168<<8)+(1<<16)+(60<<24);
sa.sin_addr.s_addr=ipv4addr;
inet_ntop(AF_INET, &sa.sin_addr, str, INET_ADDRSTRLEN);
printf("Example from unsigned int decimal example: %s\n", str);
// Or just store it as a string to begin with...
inet_pton(AF_INET, "9.9.9.9", &(sa.sin_addr));
// or if you read it from another function, you can convert it back and print it
inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);
printf("Example from string: %s\n", str); // prints "9.9.9.9"
}
学习更多!
如您所知,一小段示例代码将有助于查看您已经尝试过的内容。请显示代码并解释UNIX系统中的繁琐或棘手之处,您可能需要考虑修改代码以使用<代码> iNETNtoA < /COD>及其亲属。您需要以不同的格式输入。(压缩为32位整数,而不是整数数组),但标准化的代码可能更健壮。sprintf就是这样做的。是的,代码会很麻烦,因为在C中处理字符串很麻烦。习惯它吧。@LeeDanielCrocker我认为;当代码编写正确时,理解它就没有问题了。我不是反对票,但可能是因为一些吹毛求疵的事情s、 例如:使用sprintf
中的指针寻址或索引(所有*ip
或所有ip[n]
)执行malloc(16*sizeof(char))
,可读性更高。@anonmessizeof(char)
的定义是1.*ip
更短。char
有一个字节大;唯一可以改变的是char中的位数,用char\u-BIT
表示。数组寻址只是一种同步糖,从a[n]
到*(a+n)
所以这真的没什么区别。我知道,这只是一个好习惯,特别是对刚开始学习的人来说C@user3386109:sizeof(char)当以前使用的char
代码被更改为wchar\u t
或int
或其他内容时,
是有利的,因为进行更改的人可以搜索出现char
的位置,并决定是否需要更改。他们不能轻易地搜索1会出现,尤其是在写入malloc(16*1)
后,即使该代码已被删除malloc(16)
。不使用“幻数”的规则适用:在从foo到bar的转换代码中,不应写入12
。1是基本数并不意味着它……不是“幻数”对于sizeof(char)
。编写代码的一部分应该是为了向读者表达意义,而sizeof(char)
向读者表示程序员正在为char
对象分配空间。如果代码只是说malloc(16)
,那么它是否丢失显然不仅仅是因为这个原因
。但是如果上面写的是malloc(16*sizeof(char))
,你可以看到它的意图。它们不是无处不在吗?不是吗:?另外,我不知道IP.ToString…太好了!但是它与他的数组格式兼容吗?
man inet_addr