读入字符串,按'~'进行拆分,如果没有找到'~'则地址非法;拆分成ip和mask后,先对mask进行检查,mask转成一个十进制的数,按位从最右边开始找第一个1,这个1的左边不能出现0;使用sscanf
对点分十进制的ip进行拆分,得到a,b,c,d,通过对a、b的判断来对ip地址进行划分。
#include <stdio.h> #include <iostream> #include <string> #include <vector> using namespace std; enum addr_type { A_type, /*A类地址*/ B_type, /*B类地址*/ C_type, /*C类地址*/ D_type, /*D类地址*/ E_type, /*E类地址*/ I_type, /*非法地址*/ P_type, /*私有地址*/ O_type, /*其他地址*/ MAX_TYPE }; void check_ip_type(const string& str, addr_type& type, bool& is_p_type) { unsigned long a,b,c,d; if(str.find_first_not_of("0123456789.") != str.npos) { type = I_type; return; } if(sscanf(str.c_str(), "%ld.%ld.%ld.%ld", &a,&b,&c,&d) != 4) { type = I_type; return; } if(a > 255 || b>255 || c>255 || d>255) { type = I_type; return; } if(a==0 || a==127) { type = O_type; return; } if(a >= 1 && a<=126) { type=A_type; }else if(a>=128 && a<=191) { type=B_type; }else if(a>=192 && a<=223) { type=C_type; }else if(a>=224 && a<=239) { type=D_type; }else if(a>=240 && a<=255) { type=E_type; } if(a==10 || (a==172 && (b>=16 && b<=31)) || (a==192 && b==168)) { is_p_type = true; } } bool valid_mask(const string& str) { unsigned long a,b,c,d; if(str.find_first_not_of("0123456789.") != str.npos) return false; if(sscanf(str.c_str(), "%ld.%ld.%ld.%ld", &a,&b,&c,&d) != 4) return false; if(a==255 && b==255 && c==255 && d==255) return false; if(a==0 && b==0 && c==0 && d==0) return false; if(a > 255 || b>255 || c>255 || d>255) return false; unsigned long mask = (a<<24) | (b << 16) | (c << 8) | d; //从最低位的bit位查找为1的bit位,该位的左边不能出现0 bool found_bit1 = false; while(mask) { if(found_bit1) { if((mask&1) == 0) { return false; } } else { found_bit1 = ((mask&1)==1); } mask>>=1; } return true; } void fun(int count[], const string& str) { size_t offset = str.find('~'); if(offset != str.npos) { string ip = str.substr(0,offset); string mask = str.substr(offset+1); //检查mask是否非法; if(valid_mask(mask)) { addr_type type; bool is_p_type = false; check_ip_type(ip,type,is_p_type); //相应的地址类型增加; count[type]++; //私有地址增加; if(is_p_type) { count[P_type]++; } } else { count[I_type]++; } } else { count[I_type]++; } } int main() { int count[MAX_TYPE]={0}; string str; while(cin >> str) fun(count, str); //不输出其他类型的地址(0.*.*.*/127.*.*.*); for(int i=0;i<MAX_TYPE-1;i++) { printf("%d ", count[i]); } return 0; }