本题将会给出
条地址信息,确切数字未知,您需要一直读取至文件结尾;您也可以参考 牛客网在线判题系统使用帮助 获得更多的使用帮助。每条地址信息描述如下:
每行输入一个
形式的 IP 地址和一个
形式的子网掩码,中间用波浪线(
)分隔。保证
要么为空,要么是一个
到
间的整数。
在一行上输出七个整数,分别代表 A 类地址数、B 类地址数、C 类地址数、D 类地址数、E 类地址数、错误 IP 或错误子网掩码数、私有 IP 数。
10.70.44.68~1.1.1.5 1.0.0.1~255.0.0.0 192.168.0.2~255.255.255.0 19..0.~255.255.255.0
1 0 1 0 0 2 1
在这个样例中:
第一条地址信息:掩码非法;
第二条地址信息:IP 格式和掩码均合法,属于 A 类;
第三条地址信息:IP 格式和掩码均合法,属于 C 类私有地址;
第四条地址信息:IP 格式非法。
统计得到
个 A 类,
个 B 类,
个 C 类,
个 D 类,
个 E 类,
个错误条目,
个私有地址。
0.201.56.50~255.255.255.0 127.201.56.50~255.255.111.255
0 0 0 0 0 0 0
在这个样例中,两条地址信息均属于上方提示中提到的特殊 IP 地址,不需要处理,直接跳过。特别需要注意地,第二条地址的子网掩码是非法的。但是因为该条为特殊 IP 地址,此优先级更高,所以不进入统计。
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-05-30 更新题面。
2. 2024-12-16 更新题面。
#include <stdio.h>
typedef struct ip{
int A;
int B;
int C;
int D;
int E;
int error;
int privacy;
} IP;
int main(){
IP ipv4={0};
char str[200];
int ip[4]={0},mask[4]={0};
int count;
while(scanf("%s",str) !=EOF){
count=sscanf( str,"%d.%d.%d.%d~%d.%d.%d.%d", &ip[0],&ip[1],&ip[2],&ip[3], &mask[0],&mask[1],&mask[2],&mask[3]);
if(ip[0]==0 || ip[0]==127){
continue;
}
if(count != 8){
ipv4.error++;
continue;
}
int mask32 = (mask[0] << 24)+(mask[1] << 16) +(mask[2]<<8)+mask[3];
if(((~mask32+1)& ~mask32) || ! ~mask32){
ipv4.error++;
continue;
}
if(ip[0] >=1 && ip[0]<=126){
ipv4.A++;
}
else if (ip[0]>=128 && ip[0] <=191) {
ipv4.B++;
}
else if (ip[0]>=192 && ip[0] <= 223) {
ipv4.C++;
}
else if (ip[0] >= 224 && ip[0] <=239) {
ipv4.D++;
}
else {
ipv4.E++;
}
if(ip[0]==10 || (ip[0]==172&&ip[1]>= 16&&ip[1]<=31) || (ip[0]==192 &&ip[1]==168)){
ipv4.privacy++;
}
}
printf("%d %d %d %d %d %d %d",ipv4.A,ipv4.B,ipv4.C,ipv4.D,ipv4.E,ipv4.error,ipv4.privacy);
return 0;
} #include <stdio.h>
#include <string.h>
#include <stdlib.h>
int g_ipa = 0;
int g_ipb = 0;
int g_ipc = 0;
int g_ipd = 0;
int g_ipe = 0;
int g_err = 0;
// int g_mask_err = 0;
int g_ip_pri = 0;
// int g_ipe = 0;
unsigned int ipa_min,ipa_max;
unsigned int ipb_min,ipb_max;
unsigned int ipc_min,ipc_max;
unsigned int ipd_min,ipd_max;
unsigned int ipe_min,ipe_max;
unsigned int ipp1_min,ipp1_max;
unsigned int ipp2_min,ipp2_max;
unsigned int ipp3_min,ipp3_max;
unsigned int ipstr_to_u32(char *ip)
{
unsigned int ipa = 0;
int tmp[4];
int cnt = sscanf(ip,"%d.%d.%d.%d",&tmp[0],&tmp[1],&tmp[2],&tmp[3]);
if(cnt != 4) //匹配次数
{
return 0;
}
ipa = ipa | (tmp[0] << 24);
ipa = ipa | (tmp[1] << 16);
ipa = ipa | (tmp[2] << 8);
ipa = ipa | (tmp[3] );
return ipa;
}
//return 0 :ip err
int check_ip_valide(char *ip)
{
int ipa = ipstr_to_u32(ip);
if(ipa == 0 || strlen(ip) < 7)
{
return 0;
}
return ipa;
}
#define bitset(x,p) ((x >> p) & 0x1)
#define u32tobits(x,buf) for(int __i = 0;__i<32;__i++) buf[32-__i-1]= bitset(x,__i)==1?'1':'0';
int check_mask_valid(char *mask)
{
unsigned int m = ipstr_to_u32(mask);
char maskstr[33] = {0};
u32tobits(m, maskstr);
// printf("mask str %s\n",maskstr);
if(strstr(maskstr,"01") || m == 0xffffffff || m == 0) //需要返回来
{
// printf("mask error %s\n",mask);
return 0;
}
// printf("mask %s %u ->%s ok\n",mask,m, maskstr);
return 1;
}
int check_line(char *line)
{
char *p,*ph = line;
char *ip = line;
char *mask ;
unsigned int ipi;
p = strchr(ph,'~');
if(!p){
// g_err++;
return 0;
}
*p = '\0';
mask = p+1;
ipi = check_ip_valide(ip);
if(0 == ipi || 0 == check_mask_valid(mask))
{
g_err++;
// printf("%s %s error %d\n",ip,mask,g_err);
return 0;
}else{
if(ipi>= ipa_min && ipi <= ipa_max)
{
g_ipa++;
}else if(ipi>= ipb_min && ipi <= ipb_max)
{
g_ipb++;
}else if(ipi >= ipc_min && ipi <= ipc_max)
{
g_ipc++;
}else if(ipi >= ipd_min && ipi <= ipd_max)
{
g_ipd++;
}else if(ipi >= ipe_min && ipi <= ipe_max)
{
g_ipe++;
}
if((ipi >= ipp1_min && ipi <= ipp1_max) || (ipi >= ipp2_min && ipi <= ipp2_max) || (ipi >= ipp3_min && ipi <= ipp3_max))
{
g_ip_pri++;
}
}
return 0;
}
void init_iptype()
{
ipa_min = ipstr_to_u32("1.0.0.0");
ipa_max = ipstr_to_u32("126.255.255.255");
ipb_min = ipstr_to_u32("128.0.0.0");
ipb_max = ipstr_to_u32("191.255.255.255");
ipc_min = ipstr_to_u32("192.0.0.0");
ipc_max = ipstr_to_u32("223.255.255.255");
ipd_min = ipstr_to_u32("224.0.0.0");
ipd_max = ipstr_to_u32("239.255.255.255");
ipe_min = ipstr_to_u32("240.0.0.0");
ipe_max = ipstr_to_u32("255.255.255.255");
ipp1_min = ipstr_to_u32("10.0.0.0");
ipp1_max = ipstr_to_u32("10.255.255.255");
ipp2_min = ipstr_to_u32("172.16.0.0");
ipp2_max = ipstr_to_u32("172.31.255.255");
ipp3_min = ipstr_to_u32("192.168.0.0");
ipp3_max = ipstr_to_u32("192.168.255.255");
}
//输入一行都要做一次校验
int main() {
char line[48];
init_iptype();
while(scanf("%s",line) != EOF)
{
check_line(line);
memset(line,0,sizeof(line));
}
printf("%d %d %d %d %d %d %d",g_ipa,g_ipb,g_ipc,g_ipd,g_ipe,g_err,g_ip_pri);
return 0;
} #include <stdio.h>
#include <string.h>
#include <stdlib.h>
//本题有个学习点就是如何循环输入
//自测都可以过但是提交提示段错误
//IP地址检测
int legalIP(char* a)
{
int i,j=1;
int num[4]={0};
num[0] = atoi(&a[0]);
for(i=0; i<=strlen(a); i++)
{
if(a[i] == '.')
{
if(a[i+1] >= '0' && a[i+1] <= '9')
{
num[j] = atoi(&a[i+1]);
j++;
}
}
}
if(j == 4 && (num[0]>=1 && num[0]<=255) && (num[1]>=0 && num[0]<=255) && (num[2]>=0 && num[0]<=255) && (num[3]>=0 && num[0]<=255))
{
return 1;
}
else {
return 0;
}
}
//三位数掩码是否合法
int legalMask2(int a)
{
int i=255;
while(i >= 0)
{
if(a == (i & 255))
{
return 1;
}
i = i << 1;
}
return 0;
}
//掩码是否合法
int legalMask(char* a)
{
int i,j=1;
int num[4]={0};
num[0] = atoi(&a[0]);
for(i=0; i<=strlen(a); i++)
{
if(a[i] == '.')
{
if(a[i+1] >= '0' && a[i+1] <= '9')
{
num[j] = atoi(&a[i+1]);
j++;
}
}
}
if(j == 4)
{
if(num[0] == 255)
{
if(num[1] == 255)
{
if(num[2] == 255)
{
if(legalMask2(num[3]) && num[3] != 255)
return 1;
else
return 0;
}
else if(legalMask2(num[2]) && num[3] == 0)
{
return 1;
}
else {
return 0;
}
}
else if(legalMask2(num[1]) && num[2] == 0 && num[3] == 0)
{
return 1;
}
else {
return 0;
}
}
else if(legalMask2(num[0]) && num[1] == 0 && num[2] == 0 && num[3] == 0 && num[0] != 0)
{
return 1;
}
else {
return 0;
}
}
else {
return 0;
}
}
int main() {
char input[1000][40]={0};
char IP[1000][20]={0},Mask[1000][20]={0};
int i=0,j=0;
int num[7]={0};
//直接用for循环输入不进来
while(scanf("%s",&input[i][0]) != EOF)
{
for(j=0; j<=40; j++)
{
if(input[i][j] == '~')
{
input[i][j] = '\0';
strcpy(&IP[i][0], &input[i][0]);
strcpy(&Mask[i][0], &input[i][j+1]);
break;
}
}
if(legalIP(&IP[i][0]) && legalMask(&Mask[i][0]))
{
if(atoi(&IP[i][0]) >=1 && atoi(&IP[i][0]) <=126)
num[0] += 1;
else if(atoi(&IP[i][0]) >=128 && atoi(&IP[i][0]) <=191)
num[1] += 1;
else if(atoi(&IP[i][0]) >=192 && atoi(&IP[i][0]) <=223)
num[2] += 1;
else if(atoi(&IP[i][0]) >=224 && atoi(&IP[i][0]) <=239)
num[3] += 1;
else if(atoi(&IP[i][0]) >=240 && atoi(&IP[i][0]) <=255)
num[4] += 1;
if(atoi(&IP[i][0]) == 10)
num[6] += 1;
if(atoi(&IP[i][0]) == 172 && (atoi(&IP[i][4]) >=16 && atoi(&IP[i][4]) <=31))
num[6] += 1;
if(atoi(&IP[i][0]) == 192 && atoi(&IP[i][4]) == 168)
num[6] += 1;
}
else if(atoi(&IP[i][0]) == 0 || atoi(&IP[i][0]) == 127)
i = i;
else {
num[5] += 1;
}
i++;
}
printf("%d %d %d %d %d %d %d",num[0],num[1],num[2],num[3],num[4],num[5],num[6]);
return 0;
} #include <stdio.h>
#include <string.h>
int check(int n)
{
int flag = 0, i, b = 7;
int a[8];
memset(a, 0, 32);
while(n)
{
a[b--] = n % 2;
n /= 2;
}
for(i = 0; i < 8; i++)
{
if(a[i] == 0)
flag = 1;
else if(a[i] == 1 && flag)
return 1;
}
return 0;
}
int main()
{
int i, j, n, b[7], flag = 0;
char ch;
int a[1000][8];
memset(a, -1, 8000);
memset(b, 0, 28);
for(i = 0; 1; i++)
{
for(j = 0; j < 8; j++)
{
scanf("%d", &a[i][j]);
ch = getchar();
}
if(ch == EOF)
break;
}
n = i;
for(i = 0; i < n; i++)
{
if(a[i][0] == 0 || a[i][0] == 127)
continue;
if((a[i][4] == 0 && a[i][5] == 0 && a[i][6] == 0 && a[i][7] == 0) || (a[i][4] == 255 && a[i][5] == 255 && a[i][6] == 255 && a[i][7] == 255))
{
b[5]++;
continue;
}
for(j = 0; j < 8; j++)
{
if(a[i][j] == -1)
{
flag = 1;
b[5]++;
break;
}
}
for(j = 4; j < 8; j++)
{
if(a[i][j] < 255)
{
if(check(a[i][j]))
{
flag = 1;
b[5]++;
}
else
{
for(int k = j + 1; k < 8; k++)
if(a[i][k] != 0)
{
flag = 1;
b[5]++;
break;
}
}
if(flag)
break;
}
}
if(flag)
{
flag = 0;
continue;
}
else
{
if(a[i][0] >= 1 && a[i][0] <= 126)
{
b[0]++;
if(a[i][0] == 10)
b[6]++;
}
else if(a[i][0] >= 128 && a[i][0] <= 191)
{
b[1]++;
if(a[i][0] == 172 && (a[i][1] >= 16 && a[i][1] <= 31))
b[6]++;
}
else if(a[i][0] >= 192 && a[i][0] <= 223)
{
b[2]++;
if(a[i][0] == 192 && a[i][1] == 168)
b[6]++;
}
else if(a[i][0] >= 224 && a[i][0] <= 239)
b[3]++;
else if(a[i][0] >= 240 && a[i][0] <= 255)
b[4]++;
}
}
for(i = 0; i < 7; i++)
printf("%d ", b[i]);
printf("\n");
return 0;
} #include <stdio.h>
//将输入的字符串转换成整型存入数组中,方便判断
void change(char* str,int arr[])
{
char* start=str;
char* end=str;
int i=0;
int j =0;
for(i=0;i<32;i++)
{
if(str[i]=='.'||str[i]=='\0'||str[i]=='~')
{
if(start==end)//点后接点如19..0.
{
arr[0]=1000;
break;
}
for(;start<end;start++)
{
arr[j]=arr[j]*10+(int)(*start-'0');
}
//printf("%d ",arr[j]);
start++;
j++;
}
if(str[i]=='\0')
break;
end++;
}
}
//掩码判断
int netmask(int arr[])
{
unsigned int integerMask = 0;
//将掩码变成无符号整数
for (int i = 0; i < 4; i++)
{
integerMask += arr[i+4] << (24 - 8 * i);
//printf("%u\n",integerMask);
}
int networkBits = 0;
int hostBits = 0;
int isHostBitsStarted = 0;
for (int i = 31; i >= 0; i--)
{
if ((integerMask>> i) & 1)
{
if (isHostBitsStarted) //有0后又出现1即为错误掩码
{
return 0; // 掩码无效:主机位中有1
}
networkBits++;
}
else
{
isHostBitsStarted = 1;//开始有0,
hostBits++;
}
}
if(networkBits ==32||hostBits ==32)//全零或者全1
{
return 0;
}
return 1;
}
//类型判断
void classfication(int arr[],int output[])
{
int ret =netmask(arr);
//printf("%d\n",ret);
//五类
if(arr[0]>=1&&arr[0]<=126&&ret ==1)
{
output[0]++;
}
else if(arr[0]>=128&&arr[0]<=191&&ret ==1)
{
output[1]++;
}
else if(arr[0]>=192&&arr[0]<=223&&ret ==1)
{
output[2]++;
}
else if(arr[0]>=224&&arr[0]<=239&&ret ==1)
{
output[3]++;
}
else if(arr[0]>=240&&arr[0]<=255&&ret ==1)
{
output[4]++;
}
else if(arr[0]==0||arr[0]==127);
else
{
output[5]++;
}
//私网ip
if(arr[0]==10&& ret ==1)
{
output[6]++;
}
else if(arr[0]==172&&arr[1]>=16&&arr[1]<=31&&ret ==1)
{
output[6]++;
}
else if(arr[0]==192&&arr[1]==168&&ret ==1)
{
output[6]++;
}
}
//输出
void print(int output[])
{
//printf("\n");
for(int i=0;i<7;i++)
{
printf("%d ",output[i]);
}
}
int main() {
char ip[32]={0};
int output[7]={0};
while(scanf("%s",ip)!=EOF)
{
int arr[8]={0};
change(ip,arr);
classfication(arr,output);
}
print(output);
return 0;
} #include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。 */
int main()
{
/* 思路
输入一行后进行判断统计,然后输入下一行
*/
char astring[32] = {0};
int output[7] = {0};
int length=0;
long hide;
int i,l,error=0,n,m=0;
int number[8];
/* 循环输入,输入后直接对数据处理,统计 */
while(fgets(astring,32,stdin)!=NULL)
{
length=strlen(astring);
for(i=0;i<8;i++)
number[i]=0;
l=0;
m=0;
error = 0;//参数清零
if(astring[length-1]=='\n'){
astring[length-1]=0;
length--;
}
/* 将ip~掩码字符串拆分放进整数数组 */
for(n=0;n<8;n++)
{
while(astring[l]!='.'&&astring[l]!='~'&&astring[l]!=0)
{
if(astring[l]<'0'||astring[l]>'9')
error = 1;//ip是否有误
l++;
}
switch(l-m){
case 3:
number[n] += (astring[l-3]-'0')*100;
case 2:
number[n] += (astring[l-2]-'0')*10;
case 1:
number[n] += astring[l-1]-'0';
if(number[n]>255)
error = 1;//ip是否有误
break;
default:
error = 1;//ip是否有误
}
l++;
m=l;
}
/* 判断子网掩码是否正确 */
for(i=0;i<4;i++)
{
for(n=0;n<7;n++)
{
if((number[i+4]&(3<<n))==(1<<n))
error = 1;
}
}
if ( (!(number[4] & 1) && (number[5] & (1 << 7))) ||
(!(number[5] & 1) && (number[6] & (1 << 7))) ||
(!(number[6] & 1) && (number[7] & (1 << 7)))||
(number[4]==255&&number[5]==255&&number[6]==255&&number[7]==255)||
(number[4]==0&&number[5]==0&&number[6]==0&&number[7]==0))
error = 1;
/* 综合处理判断ip或子网掩码是否正确-注意127和0不考虑 */
if(error&&number[0]!=127&&number[0]!=0)
{
output[5]++;
}
else
{
/* 统计ABCDE和私有ip */
if(number[0]>=1&&number[0]<=126)
{
output[0]++;//a
}
else if(number[0]>=128&&number[0]<=191)
{
output[1]++;//b
}
else if(number[0]>=192&&number[0]<=223)
{
output[2]++;//c
}
else if(number[0]>=224&&number[0]<=239)
{
output[3]++;//d
}
else if(number[0]>=240&&number[0]<=255)
{
output[4]++;//e
}
if((number[0]==10)||
(number[0]==172&&number[1]>=16&&number[1]<=31)||
(number[0]==192&&number[1]==168) )
output[6]++;
}
}
/* 输出 */
for(i=0;i<6;i++)
printf("%d ",output[i]);
printf("%d",output[6]);
}
#include <stdio.h>
int main() {
int ip[4], mk[4]; //IP地址、子网掩码
int addrType[7] = {}; //地址类型
int mask, typeId; //掩码值、类型号
int endAddr[] = //类型尾地址
{126, 191, 223, 239, 255};
while (scanf("%d.%d.%d.%d~%d.%d.%d.%d", //读取IP地址和子网掩码
ip, ip + 1, ip + 2, ip + 3,
mk, mk + 1, mk + 2, mk + 3) == 8) {
if (ip[0] == 0 || ip[0] == 127) //若非指定IP类型
continue;
//合并子网掩码为掩码值
mask = (mk[0] << 24) + (mk[1] << 16) + (mk[2] << 8) + mk[3];
if (((~mask + 1) & ~mask) || !~mask) { //若掩码非连续1后0
addrType[5]++; //错误IP或掩码+1
continue;
}
if (ip[0] == 10 || (ip[0] == 192 && ip[1] == 168) ||
(ip[0] == 172 && ip[1] > 15 && ip[1] < 32)) //若为私有地址
addrType[6]++; //私有IP类型+1
for (typeId = 0; ip[0] > endAddr[typeId]; typeId++); //遍历查找匹配类型
addrType[typeId]++; //对应IP类型+1
}
for (typeId = 0; typeId < 7; typeId++) //遍历地址类型
printf("%d ", addrType[typeId]); //打印IP类型数
}
#include <stdio.h>
typedef struct ip{
int A;
int B;
int C;
int D;
int E;
int error;
int privacy;
}IP ;
int main() {
char str[100] = {};
IP ipv4 = {0};
int ip[4] = {0};
int mask[4] = {0};
while (scanf("%s", str) != EOF) { // 注意 while 处理多个 case
int ip_num = sscanf(str, "%d.%d.%d.%d~%d.%d.%d.%d", &ip[0],&ip[1],&ip[2],&ip[3],\
&mask[0],&mask[1],&mask[2],&mask[3]);
if(ip[0] == 0 || ip[0] == 127) //不属于任何一类,计数时忽略
continue;
//IP地址或子网掩码输入格式错误
if(ip_num != 8)
{
ipv4.error++;
continue;
}
//判断子网掩码合法性
if((mask[0] == 0 && mask[1] == 0 && mask[2] == 1 && mask[3] == 0)\
|| (mask[0] == 255 && mask[1] == 255 && mask[2] == 255 && mask[3] == 255))
{
ipv4.error++;
continue;
}
int mask32 = 0;
for(int i=3; i>=0; i--)
{
mask32 += mask[i] << 8*(3-i); //将子网掩码合成32位整数
}
mask32 = ~mask32 + 1; //取反为000…00111…1,然后再加1为00…01000…0,此时为2^n,如果满足就为合法掩码。
if((mask32 & (mask32-1)) != 0)
{
ipv4.error++;
continue;
}
//对正确IP地址分类
if(ip[0] >= 1 && ip[0] <= 126)
{
ipv4.A++;
}
else if(ip[0] >= 128 && ip[0] <= 191)
{
ipv4.B++;
}
else if(ip[0] >= 192 && ip[0] <= 223)
{
ipv4.C++;
}
else if(ip[0] >= 224 && ip[0] <= 239)
{
ipv4.D++;
}
else
{
ipv4.E++;
}
//私网
if((ip[0] == 10) || (ip[0] == 172 && ip[1] >= 16 &&ip[1] <= 31) || \
(ip[0] == 192 && ip[1] == 168))
{
ipv4.privacy++;
}
}
printf("%d %d %d %d %d %d %d", ipv4.A,ipv4.B,ipv4.C,ipv4.D,ipv4.E,ipv4.error,ipv4.privacy);
return 0;
} #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#define IPV4_ADR_AND_MASK_RE "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$"
int main() {
char str[50];
int class_A_count = 0, class_B_count = 0, class_C_count = 0, class_D_count = 0,
class_E_count = 0, wrong_ipadr_or_mask_count = 0, private_ip = 0;
while (fgets(str, 50, stdin) != NULL) { // 获取字符串
int len = strlen(str) - 1;
str[len] = '\0';
// 将字符串拆分成IPv4地址和掩码
char* ip_adr = strtok(str, "~");
char* mask = strtok(NULL, "~");
// 判断IPv4地址是否合法
regex_t regex;
regcomp(®ex, IPV4_ADR_AND_MASK_RE, REG_EXTENDED);
int reti = regexec(®ex, ip_adr, 0, NULL, 0);
if (reti) {
// IPv4地址不合法
wrong_ipadr_or_mask_count += 1;
regfree(®ex);
continue;
}
// 判断IPv4地址是否为 0.*.*.* 或 127.*.*.*
int first_field = atoi(ip_adr);
if (first_field == 0 || first_field == 127) {
// IPv4地址是 0.*.*.* 或 127.*.*.*
regfree(®ex);
continue;
}
// 判断掩码是否合法
reti = regexec(®ex, mask, 0, NULL, 0);
if (reti) {
// 掩码不合法(情况1)
wrong_ipadr_or_mask_count += 1;
regfree(®ex);
continue;
}
regfree(®ex);
unsigned bin_mask = 0;
char* temp_p = mask;
unsigned temp = atoi(temp_p);
for (int i = 0; i < 4; ++i) {
bin_mask |= temp << ((3 - i) * 8);
if (i != 3) {
temp_p = strchr(temp_p, '.') + 1;
temp = atoi(temp_p);
}
}
if (bin_mask == 0 || bin_mask == 0xFFFFFFFF ||
((bin_mask | (bin_mask - 1)) != 0xFFFFFFFF)) {
// 掩码不合法(情况2)
wrong_ipadr_or_mask_count += 1;
continue;
}
// 判断IPv4地址是否为A类
if (1 <= first_field && first_field <= 126) {
// IPv4地址是A类
class_A_count += 1;
// 判断是否是A类的私网IPv4地址
if (first_field == 10) {
// 是A类的私网IPv4地址
private_ip += 1;
}
continue;
}
// 判断IPv4地址是否为B类
int second_filed = atoi(strchr(ip_adr, '.') + 1);
if (128 <= first_field && first_field <= 191) {
// IPv4地址是B类
class_B_count += 1;
// 判断是否是B类的私网IPv4地址
if (first_field == 172 && (16 <= second_filed && second_filed <= 31)) {
// 是B类的私网IPv4地址
private_ip += 1;
}
continue;
}
// 判断IPv4地址是否为C类
if (192 <= first_field && first_field <= 223) {
// IPv4地址是C类
class_C_count += 1;
// 判断是否是C类的私网IPv4地址
if (first_field == 192 && second_filed == 168) {
// 是C类的私网IPv4地址
private_ip += 1;
}
continue;
}
// 判断IPv4地址是否为D类
if (224 <= first_field && first_field <= 239) {
// IPv4地址是D类
class_D_count += 1;
continue;
}
// 判断IPv4地址是否为E类
if (240 <= first_field && first_field <= 255) {
// IPv4地址是E类
class_E_count += 1;
continue;
}
}
// 输出统计结果
printf("%d %d %d %d %d %d %d\n", class_A_count, class_B_count, class_C_count,
class_D_count, class_E_count, wrong_ipadr_or_mask_count, private_ip);
return 0;
} #include <stdio.h>
int main()
{
char ip_buf[30] ;
int ip[4], mask[4];
int A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, S = 0;
int i, mask_num, mask_flag;
while(scanf("%s", ip_buf) != EOF)
{
if(sscanf(ip_buf, "%d.%d.%d.%d~%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3], &mask[0], &mask[1], &mask[2], &mask[3]))
{
if(ip[0] == 0 || ip[0] == 127) // 忽略地址不用判断掩码是否错误
continue;
// 判断IP格式是否错误
for(i = 0; i < 4; i++)
mask_num = mask_num << 8 | mask[i];
if(mask_num == 0x00 || mask_num == 0xFFFFFFFF) // 非法掩码
{
F++;
continue;
}
/* 从最后一位判断掩码是否有效 */
for(i = 0, mask_flag = 0; i < 32; i++)
{
if((mask_num & 0x01) != mask_flag) // 出现不一致
{
if(mask_flag == 0) // 0 往前就是1
{
mask_flag = 1;
}
else // 1往前不能为0,掩码错误
{
F++;
break;
}
}
mask_num >>= 0x01;
}
if(i == 32)
{
// 是否为私网地址
if((ip[0] == 10) || (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) || (ip[0] == 192 && ip[1] == 168))
S++;
// 私网地址和公有地址可以共用
if(ip[0] <= 126) A++;
else if(ip[0] <= 191) B++;
else if(ip[0] <= 223) C++;
else if(ip[0] <= 239) D++;
else E++;
}
}
}
printf("%d %d %d %d %d %d %d", A, B, C, D, E, F, S);
}