IPV4:ip地址由32个bit位构成(32个二进制位)
IPV6:ip地址由128个二进制位构成
(一)将无符号整型转换成点分十进制的形式
方法一:IP右移动+&
该方法简单易想,但是不好,因为将X拷入buff需要倒着拷入,麻烦
int a = 12;
printf("%d %o %x \n", a, a, a);//printf的格式化控制符在调用_itoa_s
// 12 14 C \n
void Uint_To_Str(char* buff, unsigned int ip)
{
assert(buff != nullptr);
unsigned char x;
char str[10];
for (int i = 0;i < sizeof(unsigned int);++i)
{// 4
x = ip & 0x000000FF;//两个F才代表8个1,一个字节
//与后的值是一个整型,给x,并且需要将x转换成字符串
ip = ip >> 8;
//_itoa_s函数将整型转换成字符串
_itoa_s(x, str, 10);//将x转换成字符串,并且以十进制的形式,放在数组str中
}
}
int main()
{
char buff[20];
unsigned int ip = 2148205343;
Uint_To_Str(buff, ip);
return 0;
}
方法二:联合体
想法1:用ip给x的addr赋值时,占用4字节,因此想定义4个无符号char类型将每一个字节读出来
错误想法:因为s1,s2,s3,s4都共用同一块空间
union IPNode
{
unsigned int addr;
unsigned char s1, s2, s3, s4;
};
void Uint_To_Str(char* buff, unsigned int ip)
{
assert(buff != nullptr);
IPNode x;
x.addr = ip;
}
方法2:结构升级**(哑元)**
union IPNode
{
unsigned int addr;
struct
{
unsigned char s1;
unsigned char s2;
unsigned char s3;
unsigned char s4;
};
};
此时哑元结构和addr共享空间
union IPNode
{
unsigned int addr;
struct
{
unsigned char s1;
unsigned char s2;
unsigned char s3;
unsigned char s4;
};
};
void Uint_To_Str(char* buff,int len, unsigned int ip)//len:buff的长度
{
assert(buff != nullptr);
IPNode x;
x.addr = ip;
sprintf_s(buff, len,"%d.%d.%d.%d", x.s4, x.s3, x.s2, x.s1);
}
int main()
{
char buff[20];
unsigned int ip = 2148205343;
Uint_To_Str(buff,20, ip);
return 0;
}
(二)将一个字符串转换成一个无符号整型
方法一:
问题1:不合法的十进制点分十进制表示:0–255
问题2:不合法的ipv4表示
解决想法:将每一个以点分割的字符串读出来,变成合法的数值然后进行拼接
int main()
{
char stra[] = { "128.11.3.31" };
char strb[] = { "377.12.34.11" };
char strc[] = { "125.11.34.23.23.43" };
//atoi:将字符串转换成整型,但是转换时遇见点就不转换了
char* p = stra;
int s1 = atoi(p);
p = strchr(p, '.');//strchr函数在p中找出‘.’,并返回‘.’的位置
p = p + 1;
int s2 = atoi(p);
p = strchr(p, '.');
p = p + 1;
int s3 = atoi(p);
p = strchr(p, '.');
p = p + 1;
int s4 = atoi(p);
return 0;
}
方法二:
分析代码:
#include<stdio.h>
#include<string.h> //strchr
#include<stdlib.h> // _itoa_s
#include<assert.h>
#include<limits.h>
//Str_To_Uint
union IPNode//4字节
{
unsigned int addr;
//struct
//{
// unsigned char s1;
// unsigned char s2;
// unsigned char s3;
// unsigned char s4;
//};
unsigned char sx[4];//0--->低位;3--->高位
};
int main()
{
char stra[] = { "128.11.3.31" };
char strb[] = { "377.12.34.11" };
char strc[] = { "125.11.34.23.23.43" };
IPNode x;
int s[4];
char ch;
int n = sscanf_s(stra,"%d.%d.%d.%d%c", &s[3], &s[2], &s[1], &s[0]);
if (n != 4)
{
return -1;
}
else
{
for (int i = 3;i >= 0;--i)
{
if (s[i] >= 0 && s[i] <= 255)//合法的IP地址
{
x.sx[i] = s[i];//4字节给1字节,直接切片,截取低位
}
else
{
printf("error \n");
return 1;
}
}
}
printf("%u \n", x.addr);
/*
int s1, s2, s3, s4;
int len2=scanf_s("%d.%d", &s1, &s2);//从标准输入设备读取数据;返回值len2是正确接受数据的个数
//fscanf_s(stdin, "%d.%d", &s1, &s2);//从文件中读取数据
sscanf_s(stra,"%d.%d.%d.%d",&s4,&s3,&s2,&s1);//从缓冲区中stra中读取数据
//int len1 = printf("a=%d b=%d", a, b);//返回值len1是格式化后字符串的长度
*/
return 0;
}
标准解析代码:
#include<stdio.h>
#include<string.h> //strchr
#include<stdlib.h> // _itoa_s
#include<assert.h>
#include<limits.h>
//Str_To_Uint
union IPNode//4字节
{
unsigned int addr;
unsigned char sx[4];//0--->低位;3--->高位
};
unsigned int Str_To_Uint(char* stra)
{
assert(stra != nullptr);
IPNode x;
int s[4];
char ch;
int n = sscanf_s(stra, "%d.%d.%d.%d%c", &s[3], &s[2], &s[1], &s[0]);
if (n != 4)
{
return -1;
}
else
{
for (int i = 3;i >= 0;--i)
{
if (s[i] >= 0 && s[i] <= 255)//合法的IP地址
{
x.sx[i] = s[i];//4字节给1字节,直接切片,截取低位
}
else
{
return -1;
}
}
}
return x.addr;
}
int main()
{
char stra[] = { "128.11.3.31" };
char strb[] = { "377.12.34.11" };
char strc[] = { "125.11.34.23.23.43" };
unsigned int x = Str_To_Uint(stra);
printf("%u \n", x);
return 0;
}