aa(Ip_addr);
bb(Ip_addr);
cc();
ee(sub_net);
dd();
cout<<"是否继续是(其他键)否(n)";
cin>>jj;}
}
(2)
题目要求:
编写程序,判断一个IP地址是否合法,并判断该地址是否属于一个给定的子网。
要求:
1)以命令行格式运行:
ip_testsubnet/maskip_addr
其中ip_test为程序名;subnet为子网号;mask是一个数值,代表子网掩码连续1的个数;ip_addr是要测试的ip地址。
例如,要测试的IP地址为202.113.16.10,子网号为202.113.16.0,子网掩码为255.255.255.0
2)判断subnet和ip_addr的合法性(注意考虑全面,比如以下IP均为不合法123..2.1
123.23$.2.1
123.12345.2.1
123.23.45.2.1
3)判断掩码的合法性
4)在IP地址合法的前提下,判断ip_addr是否属于子网subnet
5)输出命令行中的IP是否合法,掩码是否合法(可适当给出不合法原因)以及ip_addr是否属于子网subnet。
我做的程序代码如下:
#include
#include
#include
voidsplit(char*addr,int*num)
{//将点分十进制的字符串转换为数值数组
chartemp[4][10];
inti,j,k,len=strlen(addr);
for(i=0;i<4;i++)
for(j=0;j<10;j++)
{temp[i][j]='\0';}
j=0;
k=0;
for(i=0;i{if(addr[i]!
='.')
{temp[j][k]=addr[i];
k++;}
else
{j++;
k=0;}
}
for(i=0;i<4;i++)
{num[i]=atoi(temp[i]);}
}
inttoBinary(inta)
{//将十进制数转换为二进制数
if(a/2==0)returna%2;
returna%2+toBinary(a/2)*10;
}
char*toString(int*a)
{//将二进制的数值数组转换32个字符长的字符指针
char*temp=newchar[33];
inti;
boolflag=false;
char*eight=newchar(),*seven=newchar(),*six=newchar(),*five=newchar(),*four=newchar(),
*three=newchar(),*two=newchar(),*one=newchar();
for(i=0;i<4;i++)
{itoa(a[i]/10000000,eight,10);
itoa(a[i]/1000000%10,seven,10);
itoa(a[i]/100000%10,six,10);
itoa(a[i]/10000%10,five,10);
itoa(a[i]/1000%10,four,10);
itoa(a[i]/100%10,three,10);
itoa(a[i]/10%10,two,10);
itoa(a[i]%10,one,10);
if(flag==true)
{strcat(temp,eight);}
else
{strcpy(temp,eight);
flag=true;}
strcat(temp,seven);
strcat(temp,six);
strcat(temp,five);
strcat(temp,four);
strcat(temp,three);
strcat(temp,two);
strcat(temp,one);
}
returntemp;
}
inttest(char*addr)
{//测试IP等点分十进制数的合法性,返回0则不合法,返回1则合法
intlen=strlen(addr);
if(len>15)
{cout<<"地址总长超过了15!
"<return0;}
intdotnum=0;
for(inti=0;i{if((addr[i]<'0'||addr[i]>'9')&&addr[i]!
='.')
{
cout<<"地址中包含非法字符!
"<return0;}
if(addr[i]=='.')
dotnum++;}
if(dotnum>3)
{cout<<"地址中分隔符只能为3个!
"<return0;}
for(i=0;i{if(addr[i]=='.'&&addr[i+1]=='.')
{cout<<"地址中不能出现连续的分隔符!
"<return0;
}
}
if(addr[len-1]=='.')
{
cout<<"地址最后位不能为分隔符!
"<return0;
}
inta[4];
split(addr,a);
for(i=0;i<4;i++)
{if(a[i]>255||a[i]<0)
{
cout<<"地址数字不在范围0-255之间!
"<return0;
}
}
if(a[0]<1)
{cout<<"地址首位不能为0!
"<return0;}
return1;
}
voidmain(intargc,char*argv[])
{if(argc!
=3)
{cout<<"请按以下格式输入命令行:
ip_testsubnet/maskipaddr"<return;
}
inti,j=0;
boolflag=false;
char*ipaddr=newchar[strlen(argv[2])];
strcpy(ipaddr,argv[2]);//字符串格式的IP地址
char*subnet_mask=newchar[strlen(argv[1])];
strcpy(subnet_mask,argv[1]);
char*subnet=newchar[16];
char*mask_num=newchar[4];
intlen=strlen(subnet_mask);
for(i=0;i{if(subnet_mask[i]=='/')
{flag=true;
subnet[j]='\0';
j=0;
continue;
}
if(flag==false)
{subnet[j]=subnet_mask[i];
j++;
}
else
{mask_num[j]=subnet_mask[i];
j++;
}
}
mask_num[j]='\0';
cout<<"IP地址测试:
";
if(test(ipaddr)==1)
{cout<else
{cout<return;}
cout<<"子网号测试:
";
if(test(subnet)==1)
{cout<else
{cout<return;
}
intmaskn=atoi(mask_num);
cout<<"掩码中1的个数测试:
";
if(maskn>0&&maskn<=32)
{cout<<"个数为:
"<"<else
{cout<<"个数为:
"<"<//将IP地址与子网号转成数值放在数组中
intnbipaddr[4],nbsubnet[4];
split(ipaddr,nbipaddr);//分离,未转成二进制,只是分离成十进制
split(subnet,nbsubnet);
for(i=0;i<4;i++)
{nbipaddr[i]=toBinary(nbipaddr[i]);//将分离出来的十进制转换为二进制
nbsubnet[i]=toBinary(nbsubnet[i]);
}
char*cbipaddr=newchar[33];
char*cbsubnet=newchar[33];
cbipaddr=toString(nbipaddr);//将二进制数组转换为32位的二进制字符指针
cbsubnet=toString(nbsubnet);
//测试是否在子网内,是否需转成二进制比较,可用递归转成二进制(除二取余)
for(i=0;i{if(cbipaddr[i]!
=cbsubnet[i])
{cout<<"IP地址:
"<return;
}
}
cout<<"IP地址:
"<}
对于判断是否属于给定的子网,我采用的方式是将IP地址与子网地址的点分十进制方式都转化为不带分隔符的二进制数,都是32位长,对于给予的子网中1的个数,我只判断其范围,对于其他原因,并示考虑到,希望你看到后,能给予提示,谢谢!