利用字符流进行数据读入真的是非常方便
识别有效的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,返回错误
查看19道真题和解析