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) fomat, where xxx is between 0 and 255.
I've used Boost.Regex for that in the past. You can also find it in TR1.
The RE I used:
"^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{"
"2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25"
"[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$";
It's long, but it makes sure each portion is between 0 and 255. I believe I got it from regexlib.com.
Another option is to call inet_addr(), which will convert a string to an address. It will return a failure code if it's not a valid ip address.
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);
}
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
If you wanted to write this yourself rather than use a library then
atoi() to convert characters to ints will let you test the range of each number, and some strcmp's between the "."'s. You can also do some quick checks, such as the length of the string (should be less than 16 characters (not including null terminator), number of dots. etc.
But, it's probably MUCH easier to use existing code.
If you don't want the overhead of Boost or TR1 you could search for the dots and check if the characters between them are numbers from 0 to 255.
You probably want the inet_pton - which returns -1 on failure, and supports both the IPv4 and future IPv6 addresses. If you still need to write your own IP address system, remember that a standard 32-bit hex number is a valid IP address but not in dotted-decimal notation.
This function both verifies the address, and also allows you to use the same address in related socket calls.
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;
}
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
The solution that I settled on was:
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;
}
This works for most cases that were mentioned in other answers. It doesn't recognize IP addresses with octal or hex formatting, but that's acceptable for my application.
Boost.Asio provides the class ip::address. If you just want to verify the string, you can use it like this:
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;
This also works for hexadecimal and octal quads. This is also a much more portable solution.
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.
Thanks StackOverFlow, I am learning in an exponential order these days :) !