总体思路

将每一行中的IP地址,子网掩码提取出来,每个点分十进制数提取出来,通过字符转整数转换成整数,将整数作为一个元素压入到IP vector和MASK vector中,在对IP和MASK逐个进行判断。
IP 只需要判断是否小于0或者大于255,如果是,直接归入错误类,继续下一个字符串的判断
对于IP第一位,如果是0 或者127 直接跳过,继续下一个字符串的判断
剩下的判断是A,B,C,D,E中的哪一类。
MASK 判断MASK是否大于255或小于0
整个MASK是否都是由255或者0组成,如果是,直接归入错误类,继续下一个字符串的判断
对于MASK是由是由特定的几个数构成,因为要求二进制前面的都是1,后面的都是0,仅仅只能够有8位数字满足要求,不是这8位数组成的一律排除。
从MASK的第1位(0 是起始)开始,判断本位是否为0,若不是,前面一位必须是255,满足子网掩码二进制数都是前面是1,后面是0.

代码

#include<iostream>
#include<sstream>
#include<cmath>
#include<vector>

using namespace std;

int string2int(string s) {
    int res = 0;
    int num = s.size();
    if (num == 0)
        return -1;
    for (int i = 0; i < s.size(); ++i) {
        res += (s[i] - '0') * pow(10, --num);
    }
    return res;
}


int main() {
    string line;
    int AIP = 0, BIP = 0, CIP = 0, DIP = 0, EIP = 0, error = 0, privateIP = 0;
    while (getline(cin, line)) {  // 读取IP地址和子网掩码
        vector<int> IP, MASK;
        string s;
        istringstream is(line);
        bool isIP = true;
        while (getline(is, s, '~')) {  // 先后取出IP和子网掩码
            string num;
            istringstream iss(s);
            if (isIP) {  // 对于IP的处理
                while (getline(iss, num, '.')) {
                    int IP_num = string2int(num);
                    IP.push_back(IP_num);
                }
                isIP = !isIP;
            } else {
                while (getline(iss, num, '.')) {
                    int MASK_num = string2int(num);
                    MASK.push_back(MASK_num);
                }
                isIP = !isIP;
            }
        }
        // IP和掩码都获取完毕,开始判断
        // 判断IP是否合法
        if(IP[0] == 0 || IP[0] == 127)
            continue;
        int i = 0;
        for (; i < 4; ++i) {
            if (IP[i] > 255 || IP[i] < 0 || (IP[i] == 0 && i == 0)) {
                ++error;
                break;
            }
        }
        if(i < 4)    // IP有误,直接归类到不合法地址
            continue;
        // 判断MASK是否合法
        i = 0;
        if((MASK[0] == 255 && MASK[1] == 255 && MASK[2] == 255 && MASK[3] == 255) || (MASK[0] == 0 && MASK[1] == 0 && MASK[2] == 0 && MASK[3] == 0)){
            ++error;
            continue;
        }
        for (; i < 4; ++i) {
            if (MASK[i] != 255 && MASK[i] != 254 && MASK[i] != 252 && MASK[i] != 248 &&
                    MASK[i] != 240 && MASK[i] !=224  && MASK[i] !=192  && MASK[i] != 128 && MASK[i] != 0) {
                break;
            }
            if (i >= 1 && (MASK[i - 1] != 255 && MASK[i] != 0)) {
                break;
            }
        }
        if(i < 4){    // MASK有误,直接归类到不合法地址
            ++error;
            continue;
        }    


        if (IP[0] == 10 || (IP[0] == 172 && (IP[1] >= 16 && IP[1] <= 31)) ||
                    (IP[0] == 192 && IP[1] == 168))    // 判断是不是私有IP
            ++privateIP;
        if (i == 4) {  // IP 地址合法

            if (IP[0] >= 1 && IP[0] <= 126)   // 判断属于哪一类IP
                ++AIP;
            else if (IP[0] >= 128 && IP[0] <= 191)
                ++BIP;
            else if (IP[0] >= 192 && IP[0] <= 223)
                ++CIP;
            else if (IP[0] >= 224 && IP[0] <= 239)
                ++DIP;
            else if (IP[0] >= 240 && IP[0] <= 255)
                ++EIP;
        }

    }

    cout << AIP << ' ' << BIP << ' ' << CIP << ' ' << DIP << ' ' << EIP << ' ' << error << ' ' << privateIP;

    return 0;
}