Как вы проверяете, что строка является действительным адресом IPv4 в C ++? - PullRequest
44 голосов
/ 25 ноября 2008

Мне не нужно проверять, что IP-адрес доступен или что-то в этом роде. Я просто хочу проверить, что строка в точечном квадрате (xxx.xxx.xxx.xxx) в формате IPv4, где xxx находится между 0 и 255.

Ответы [ 17 ]

1 голос
/ 26 мая 2018

Вы можете написать свою собственную функцию следующим образом:

bool isValidIPv4(const char *IPAddress)
{
   unsigned char a,b,c,d;
   return sscanf(IPAddress,"%d.%d.%d.%d", &a, &b, &c, &d) == 4;
}

sscanf() и sprintf() очень полезны в некоторых ситуациях. :))

1 голос
/ 24 декабря 2013

некоторые мелкие исправления для исправления некоторых случаев, например 127..0.1, 127.0.0 .. и удаления пробелов, если есть:




    #include <iostream>
    #include <vector>
    #include <string>
    #include <sstream>
    #include <algorithm>
    #include <iterator>
    #include <stdio.h>

    using namespace std;

    vector split(char* str, char delimiter)
    {
        const string data(str);
        vector elements;
        string element;
        for(int i = 0; i  0) {//resolve problem: 127.0..1
                    elements.push_back(element);
                    element.clear();
                }
            }
            else if (data[i] != ' ')
            {
                element += data[i];
            }

        }
        if (element.length() > 0)//resolve problem: 127.0..1
            elements.push_back(element);
        return elements;
    }

    bool toInt(const string& str, int* result)
    {
        if (str.find_first_not_of("0123456789") != string::npos)
            return false;

        stringstream stream(str);
        stream >> *result; // Should probably check the return value here
        return true;
    }

    /** ipResult: the good ip address, e.g. spaces are removed */
    bool validate(char* ip, string *ipResult)
    {
        const static char delimiter = '.';
        const vector parts = split(ip, delimiter);
        *ipResult = "";
        if (parts.size() != 4)
            return NULL;

        for(int i = 0; i  255)
                return NULL;

            if (i == 3) {
                *ipResult += parts[i];
            } else {
                *ipResult += (parts[i] +".");
            }

        }
        return true;
    }

    int main()
    {
        string ip;
        printf("right %d\n", validate("127.0.0.1", &ip));
        printf("good ip: %s\n", ip.c_str());
        printf("wrong %d\n", validate("127.0.0.-1", &ip));
        printf("good ip: %s\n", ip.c_str());
        printf("wrong %d\n", validate("127..0.1", &ip));
        printf("good ip: %s\n", ip.c_str());
        printf("wrong %d\n", validate("...0.1", &ip));
        printf("good ip: %s\n", ip.c_str());
        printf("wrong %d\n", validate("127.0.0.", &ip));
        printf("good ip: %s\n", ip.c_str());
        printf("right %d\n", validate("192.168.170.99", &ip));
        printf("good ip: %s\n", ip.c_str());
        printf("right %d\n", validate("127.0 .0  .1", &ip));
        printf("good ip: %s\n", ip.c_str());
        printf("\n");

        system("pause");

        return 0;
    }

1 голос
/ 25 ноября 2008

Если вам не нужны служебные данные Boost или TR1, вы можете найти точки и проверить, являются ли символы между ними числами от 0 до 255.

1 голос
/ 12 июля 2011
vector<string> &split(const string &s, char delim, vector<string> &elems) {
    stringstream ss(s);
    string item;
    while(getline(ss, item, delim)) {
       elems.push_back(item);
    }
    return elems;
}

vector<string> split(const string &s, char delim) {
   vector<string> elems;
   return split(s, delim, elems);
}


bool isIPAddress(string  ipaddr){

    if (ipaddr.length()){
            vector<string> _ip=split(ipaddr,'.');
            if (_ip.size()==4){
                    for (int i=0; i < 4; i++){
                            for (int j=0; j < _ip[i].length(); j++)
                                    if (!isdigit(_ip[i][j])) return false;
                            if ((atoi(_ip[i].c_str()) < 0) || (atoi(_ip[i].c_str()) > 255)) return false;
                    }
            return true;
            }
    }
    return false;
 }
1 голос
/ 25 ноября 2008

Вы можете сделать это очень легко, используя boost tokenizer и boost char_separator.

http://www.boost.org/doc/libs/1_37_0/libs/tokenizer/char_separator.htm

0 голосов
/ 24 мая 2019
void validate_ip_address(const std::string& s) {
    const std::string number_0_255 = "((([0-9])|([1-9][0-9])|(1[0-9][0-9]|2[0-4][0-9]|25[0-5])){1})";
    const std::string dot = "(\\.){1}";
    static const boost::regex e(number_0_255 + dot + number_0_255 + dot + number_0_255 + dot + number_0_255);
    if (!regex_match(s, e)) {
        throw std::runtime_error(std::string("Uncorrect address IP: ") + s);
    }
}
0 голосов
/ 12 января 2019

Если вы хотите получить IP-адрес в обычной форме (8.8.8.8, 192.168.1.1 и т. Д.) Затем я написал следующий код, который расширяет ответ Бьорна:

void validateIP(const std::string &IPv4_address)
{
    boost::system::error_code error_code;
    auto raw_ipv4_address = boost::asio::ip::address::from_string(IPv4_address, error_code);
    if (error_code)
    {
        throw std::invalid_argument(error_code.message());
    }

    std::string raw_to_string_form = raw_ipv4_address.to_string();
    if (raw_to_string_form.compare(IPv4_address))
    {
        throw std::invalid_argument("Input IPv4 address is invalid");
    }
}

Причина в том, что если вы передадите IP, такой как 8.88.8 или 12345 (десятичная форма) , ответ Бьорна не выдаст ошибку. (по крайней мере, с повышением 1,68) Мой код преобразует любую форму во внутреннюю структуру в Boost, затем преобразует ее обратно в десятичный формат с точками, затем мы сравниваем ее с первым полученным IP-адресом, чтобы увидеть, равны ли они, если нет, мы точно знаем, не так, как мы хотели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...