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
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;
}
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;
}
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
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