利用字符流进行数据读入真的是非常方便
识别有效的IP地址和掩码并进行分类统计
http://www.nowcoder.com/questionTerminal/de538edd6f7e4bc3a5689723a7435682
#include<bits/stdc++.h> using namespace std; void vecip2usn(vector<int> ip, unsigned int &rtn) { rtn = 0; // 将点分十进制的ip字符串转换为ip数字 for(int i=0;i<ip.size();i++){ rtn = (rtn<<8)+ip[i]; } } bool judgemask(vector<int> mask) { if(mask.size()!=4) return false; unsigned int maskt(0); vecip2usn(mask, maskt); if(maskt==0xffffffff||maskt==0x00000000) return false; unsigned int f = 0x80000000; while(maskt){ if((maskt&f)==0) break; maskt = maskt&(~f); f = f>>1; } if(maskt) return false; return true; } bool isip(vector<int> ipnum) { for(auto val:ipnum){ if(val<0||val>255) return false; } return true; } int parseip(string ip_mask, vector<int> &ipnum, vector<int> &masknum) { // 解析得到点分十进制ip地址中的数字 string ip; string mask; // 先得到ip和掩码的字符串 int posbol = ip_mask.find('~'); ip = string(ip_mask.begin(),ip_mask.begin()+posbol); mask = string(ip_mask.begin()+posbol+1, ip_mask.end()); replace(ip.begin(),ip.end(),'.',' '); replace(mask.begin(),mask.end(),'.',' '); istringstream ipstream(ip); istringstream maskstream(mask); int t(0); while(ipstream>>t){ ipnum.push_back(t); } while(maskstream>>t){ masknum.push_back(t); } return 0; } int main() { int A(0),B(1),C(2),D(3),E(4),ERR(5),PRI(6); vector<int> out(7, 0); string ip; while(cin>>ip) { vector<int> ipnum; vector<int> masknum; parseip(ip, ipnum, masknum); if(ipnum.size()!=4||masknum.size()!=4){ out[ERR]++; // 错误的IP或者掩码 continue; } if(judgemask(masknum)==false||isip(ipnum)==false) { out[ERR]++; continue; } if(ipnum[0]==0||ipnum[0]==127) { continue; } if(ipnum[0]>=1&&ipnum[0]<=126){ out[A]++; if(ipnum[0]==10) out[PRI]++; continue; } if(ipnum[0]>=128&&ipnum[0]<=191){ out[B]++; if(ipnum[0]==172&&ipnum[1]<=31&&ip[1]>=16) out[PRI]++; continue; } if(ipnum[0]>=192&&ipnum[0]<=223){ out[C]++; if(ipnum[0]==192&&ipnum[1]==168) out[PRI]++; continue; } if(ipnum[0]>=224&&ipnum[0]<=239){ out[D]++; } if(ipnum[0]>=240){ out[E]++; } } for(int i=0;i<out.size()-1;i++) { cout<<out[i]<<' '; } cout<<out.back()<<endl; return 0; }
parseip()先读入字符串,然后找到~的位置,然后分开ip和掩码,再用replace替换'.' 为空格读入ip和掩码。
点分十进制如果没有读入4个数字都是错误的
vecip2usn把ip转换成一个无符号整形数
judgemask判断mask是否正确,先判断是否全1或全0,然后从左到右依次把1置为0,碰到0停止,如果得到的mask不为0,返回错误