我有一个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",'.');
}
}
有人可以提出更好的方法吗?
答案 0 :(得分:2)
使用单个sprintf()
在单个调用中格式化所有ip地址八位位组,而不是像在执行循环操作那样简单而容易。
如果缓冲区可以是局部变量。
char buffer[16];
const int ip[4] = {172,0,0,1};
sprintf(buffer, "%d.%d.%d.%d", *ip, ip[1], ip[2], ip[3]);
printf("IP address is: %s", buffer);
或者,如果您需要使用动态内存,则可以执行以下操作。
char * buffer = malloc(16);
const int ip[4] = {172,0,0,1};
if(!buffer) {
perror("malloc");
exit(1);
}
sprintf(buffer, "%d.%d.%d.%d", *ip, ip[1], ip[2], ip[3]);
printf("IP address is: %s", buffer);
free(buffer);
在上面的代码中,我使用了动态内存分配来创建缓冲区,并使用sprintf
向其中写入数据。
请注意,malloc(16)
-sizeof(char)
在定义上等于1
,因此我们不需要写malloc(sizeof(char) * 16)
。
答案 1 :(得分:-2)
更好的方法是使用可移植的库函数!
它将:
例如:
#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"
}
如果您使用的是Linux,请尝试:
man inet_addr
了解更多!