Как Вы проверяете это, строка является допустимым адресом IPv4 в C++?

47
задан Bill the Lizard 2 April 2014 в 17:03
поделиться

10 ответов

Вы, вероятно, хотите inet_pton, который возвращается-1 для недопустимого аргумента AF, 0 для недопустимого адреса, и +1 для допустимого IP-адреса. Это поддерживает и IPv4 и будущие адреса IPv6. Если все еще необходимо записать собственную обработку IP-адреса, помните, что стандартное 32-разрядное шестнадцатеричное число является допустимым IP-адресом. Не все адреса IPv4 находятся в десятичном представлении с разделением точками.

Эта функция и проверяет адрес, и также позволяет Вам использовать тот же адрес в связанных вызовах сокета.

52
ответ дан gary 26 November 2019 в 19:10
поделиться

Если Вы не хотите издержки Повышения или TR1, Вы могли бы искать точки и проверить, являются ли символы между ними числами от 0 до 255.

1
ответ дан EricSchaefer 26 November 2019 в 19:10
поделиться

Вы могли выполнить это очень легко с токенизатором повышения и повысить char_separator.

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

1
ответ дан Marcin 26 November 2019 в 19:10
поделиться

Если Вы хотели записать это сами, а не пользоваться библиотекой тогда

, atoi () для преобразования символов в ints позволит Вам протестировать диапазон каждого числа, и некоторый strcmp's между ". ". Можно также сделать некоторые быстрые проверки, такие как длина строки (должны быть меньше чем 16 символов (не включая пустой разделитель), количество точек. и т.д.

, Но, вероятно, НАМНОГО легче использовать существующий код.

2
ответ дан xan 26 November 2019 в 19:10
поделиться

Повышение. Regex был бы соответствующим.

bool validate_ip_address(const std::string& s)
{
   static const boost::regex e("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
   return regex_match(s, e);
}
2
ответ дан Martin Cote 26 November 2019 в 19:10
поделиться

Вот один простой метод.

bool IsIPAddress(std::string & ipaddr)
    {    

    StringTokenizer quads(ipaddr,".");

    if (quads.countTokens() != 4) return false;

    for (int i=0; i < 4; i++)
      {
      std::string quad = quads.nextToken();
      for (int j=0; j < quad.length(); j++
         if (!isdigit(quad[j])) return false;

      int quad = atoi(quads.GetTokenAt(i));
      if (quad < 0) || (quad > 255)) return false;
      }

    return true;
    }
8
ответ дан Steve 26 November 2019 в 19:10
поделиться

Это выглядит обманчиво простым, но имеет несколько ловушек. Например, многие решения, отправленные в предыдущих ответах, предполагают, что четверки находятся в основе 10 - но четверка, запускающаяся с нуля , должна рассматриваться как основу 8 (восьмеричных) чисел, следовательно например, любая четверка расстается, начиная с нуля, и содержащий цифры 8 или 9 не допустимо. Т.е., IP-адрес 192.168.1.010 не 192.168.1.10, но в действительности 192.168.1.8, и IP-адрес 192.168.019.14 не допустим, так как третья четверка содержит недопустимую основу 8 цифр 9.

, я решительно поощряю Вас использовать функции, обеспеченные библиотекой сокета, включенной в Вашу операционную систему или среду компилятора.

Редактирование: (Мысль, это было неявно, но), конечно, у Вас могут также быть шестнадцатеричные четверки, а-ля 192.168.1.0x0A для 192.168.1.10, и конечно Вы можете смешивание и подгонка к своему садистскому содержанию счастливо с помощью верхнего регистра и нижнего регистра, а-ля 0xC0.0xa8.1.010 для 192.168.1.8. Попробуйте некоторые примеры с помощью ping, если Вы хотите весело провести время. Это работает просто великолепно межплатформенное (протестированный некоторое время назад при клятве в соответствии с Linux, NetBSD и Win32.)

Дальнейшее редактирование в ответ на запрос KaluSingh Gabbar: Например, можно определить 192.168.1.10 как 0xc0a8010a, и это все еще представляет допустимый IP-адрес, а-ля:

[mihailim@home ~]$ ping 0xc0a8010a
PING 0xc0a8010a (192.168.1.10) 56(84) bytes of data.
^C
--- 0xc0a8010a ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2479ms
17
ответ дан Mihai Limbășan 26 November 2019 в 19:10
поделиться

Решение, на котором я обосновался, было:

bool Config::validateIpAddress(const string &ipAddress)
{
    struct sockaddr_in sa;
    int result = inet_pton(AF_INET, ipAddress.c_str(), &(sa.sin_addr));
    return result != 0;
}

Это работает на большинство случаев, которые были упомянуты в других ответах. Это не распознает IP-адреса с восьмеричным или шестнадцатеричным форматированием, но это приемлемо для моего приложения.

36
ответ дан Bill the Lizard 26 November 2019 в 19:10
поделиться

Boost.Asio предоставляет класс ip :: address . Если вы просто хотите проверить строку, вы можете использовать ее так:

std::string ipAddress = "127.0.0.1";
boost::system::error_code ec;
boost::asio::ip::address::from_string( ipAddress, ec );
if ( ec )
    std::cerr << ec.message( ) << std::endl;

Это также работает для шестнадцатеричных и восьмеричных четверных чисел. Это также гораздо более портативное решение.

47
ответ дан 26 November 2019 в 19:10
поделиться

I have done the same using only C stdlib functions altough it does not support octal quads as mentioned above, but that should not be an issue, I can easily add that part and give it to you. Being a beginner (student) I din't even know until now that it is possible to get an octal number within your ip. I thought it must be a decimal.

2
ответ дан 26 November 2019 в 19:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: