IP地址点分十进制打印

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;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值