How do you validate that a string is a valid IPv4 address in C++?

前端 未结 17 2054
悲哀的现实
悲哀的现实 2020-12-04 23:21

I don\'t need to validate that the IP address is reachable or anything like that. I just want to validate that the string is in dotted-quad (xxx.xxx.xxx.xxx) IPv4 format, w

相关标签:
17条回答
  • 2020-12-05 00:09

    Here's one straightforward method.

    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;
        }
    
    0 讨论(0)
  • 2020-12-05 00:11

    some minor fixes to fix some cases as 127..0.1, 127.0.0.. and remove spaces if have:

    
    
    
        #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;
        }
    
    
    0 讨论(0)
  • 2020-12-05 00:18

    Boost.Regex would be appropriate.

    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);
    }
    
    0 讨论(0)
  • 2020-12-05 00:19

    You could accomplish this very easily with boost tokenizer and boost char_separator.

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

    0 讨论(0)
  • 2020-12-05 00:20

    This looks deceptively simple but has a few pitfalls. For example, many of the solutions posted in the previous answers assume that the quads are in base 10 - but a quad starting with a zero must be treated as a base 8 (octal) number, hence for example any quad part starting with zero and containing the digits 8 or 9 is not valid. I.e, the IP number 192.168.1.010 is not 192.168.1.10 but in reality is 192.168.1.8, and the IP number 192.168.019.14 is not valid since the third quad contains the invalid base 8 digit 9.

    I emphatically encourage you to use the functions provided by the socket library included in your operating system or compiler environment.

    Edit: (Thought it was implicit, but) of course, you can also have hexadecimal quads, a la 192.168.1.0x0A for 192.168.1.10, and of course you can mix and match to your sadistic content happily using upper and lower case, a la 0xC0.0xa8.1.010 for 192.168.1.8. Try some examples using ping if you want to have fun. This works just fine cross-platform (tested a while back while swearing under Linux, NetBSD, and Win32.)

    Further edit in response to KaluSingh Gabbar's request: For example, you can specify 192.168.1.10 as 0xc0a8010a and it still represents a valid IP number, a la:

    [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
    
    0 讨论(0)
提交回复
热议问题