利用字符流进行数据读入真的是非常方便

识别有效的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,返回错误

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务