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, where xxx is between 0 and 255.
17 Answers
You probably want the inet_pton, which returns -1 for invalid AF argument, 0 for invalid address, and +1 for valid IP address. It supports both the IPv4 and future IPv6 addresses. If you still need to write your own IP address handling, remember that a standard 32-bit hex number is a valid IP address. Not all IPv4 addresses are in dotted-decimal notation.
This function both verifies the address, and also allows you to use the same address in related socket calls.

- 1,750
- 16
- 28

- 5,959
- 1
- 20
- 12
-
1Thanks for answering. I ended up writing a wrapper around inet_pton. See my answer for the (really simple) implementation. – Bill the Lizard Dec 02 '08 at 23:35
-
5**WARNING**. According to the docs, it returns -1 for invalid AF argument, 0 for invalid address, and +1 for valid IP address. – Martin Bonner supports Monica Feb 23 '16 at 14:17
-
Interestingly, the [linked documentation for inet_pton](https://man7.org/linux/man-pages/man3/inet_pton.3.html) explicitly states, that `inet_pton()` actually accepts only dotted-decimal notation. – Alex Che Nov 04 '21 at 13:33
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.

- 75,346
- 28
- 201
- 283
-
1+1 for portability and works for hex/octal quads. Best answer of the lot. – Zach Saw Sep 14 '12 at 04:21
-
1@tothphu: You should report this issue to Boost, this is most likely an oversight. – Björn Pollex Aug 27 '14 at 09:08
-
You may also want to call the `is_v4()` method on the returned address object to make sure it's not an IPv6 address. Also, seems like now it only supports exactly four decimal quads. Checked with Boost [1.73](https://wandbox.org/permlink/1gT45B8BaN64dnSr) and 1.54. – Alex Che Nov 04 '21 at 14:01
The solution that I settled on was:
#include <arpa/inet.h>
// ...
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.

- 1,543
- 3
- 21
- 40

- 398,270
- 210
- 566
- 880
-
5And this got down-voted because...? It's definitely an acceptable answer to the OP. :) – Bill the Lizard Oct 24 '09 at 14:44
-
@Wagaf That wasn't in the requirements. I updated the question. – Bill the Lizard Apr 02 '14 at 17:03
-
3I think the test should be `result != 1`. See http://pubs.opengroup.org/onlinepubs/009695399/functions/inet_ntop.html – Martin Bonner supports Monica Feb 23 '16 at 14:16
-
2
-
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

- 64,368
- 4
- 48
- 59
-
3I knew there were pitfalls, but you just opened up a whole new can of worms. :) – Bill the Lizard Nov 25 '08 at 18:15
-
Heh. I found out about it the hard way. The RFC describes this in minutiae detail, but nothing beats an upset manager demoing a product at the customer site telling you that "IP addresses with 8 or 9 in them don't work in our app's IP address controls!" Hunting for a nonexistent problem was fun... – Mihai Limbășan Nov 25 '08 at 18:48
-
1Corollary: Never assume that all people use spaces to neatly line things up. Some use zeroes. *sigh* – Mihai Limbășan Nov 25 '08 at 18:49
-
2@moocha - welcome to the real world: While octal or hex notation in IP addresses may be valid, it should NOT be encouraged! And the same goes for implementing support for it... – Roddy Dec 02 '08 at 23:45
-
3Roddy, that is *not* how the real world works. In the real world, where software robustness is regarded as somewhat important, and *especially* when networking is involved, you should try to be as tolerant as possible in what you accept and as strict as possible in what you output. – Mihai Limbășan Dec 03 '08 at 20:17
-
A note: Unlike other areas, the URLS RFC's have pretty consistently defined the IPv4 addresses as only dotted quads. The other creative methods are not allowed. Also, for the purposes of the question, the asker didn't seem to ask for a validator for everything that might be accepted by the stack, just a validator of the dotted quad format. – benc Jul 27 '09 at 06:24
-
would you please share your thoughts about this line in selected answer for this question " remember that a standard 32-bit hex number is a valid IP address but not in dotted-decimal notation." I am confused there, as you have octal numbers in dotted-decimal format ? ( am I missing something? someone please correct me) – Ramadheer Singh Nov 08 '09 at 00:14
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;
}

- 1,065
- 15
- 34
-
1
-
20There are plenty out there, or you can implement your own. Here's a pretty good one you can download: http://www.partow.net/programming/stringtokenizer/index.html (make sure the license terms are acceptable for your project) – Steve Nov 26 '08 at 00:43
You can write your own function like this:
bool isValidIPv4(const char *IPAddress)
{
unsigned char a,b,c,d;
return sscanf(IPAddress,"%d.%d.%d.%d", &a, &b, &c, &d) == 4;
}
sscanf()
and sprintf()
are very useful in some situation. :))

- 139
- 2
- 5
If you are on windows you can make use of WSAStringToAddress
and based on the return value we know, if the passed argument is valid IP or not. This supports both IPv4 & IPv6 from Windows 2000 onwards.

- 5,578
- 5
- 49
- 75

- 51
- 1
- 1
Here is the C program to validate a given IPV4 address. I have assumed that IP address is in decimal format. Please give me your thoughts on this.
// strTokenFunction.cpp : Check if the specified address is a valid numeric IP address.
// This function is equavalent to the IPAddress.TryParse() method in C#
#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>
bool isValidIpAddress(char *st)
{
int num, i, len;
char *ch;
//counting number of quads present in a given IP address
int quadsCnt=0;
printf("Split IP: \"%s\"\n", st);
len = strlen(st);
// Check if the string is valid
if(len<7 || len>15)
return false;
ch = strtok(st, ".");
while (ch != NULL)
{
quadsCnt++;
printf("Quald %d is %s\n", quadsCnt, ch);
num = 0;
i = 0;
// Get the current token and convert to an integer value
while(ch[i]!='\0')
{
num = num*10;
num = num+(ch[i]-'0');
i++;
}
if(num<0 || num>255)
{
printf("Not a valid ip\n");
return false;
}
if( (quadsCnt == 1 && num == 0) || (quadsCnt == 4 && num == 0))
{
printf("Not a valid ip, quad: %d AND/OR quad:%d is zero\n", quadsCnt, quadsCnt);
return false;
}
ch = strtok(NULL, ".");
}
// Check the address string, should be n.n.n.n format
if(quadsCnt!=4)
{
return false;
}
// Looks like a valid IP address
return true;
}
int main()
{
char st[] = "192.255.20.30";
//char st[] = "255.255.255.255";
//char st[] = "0.255.255.0";
if(isValidIpAddress(st))
{
printf("The given IP is a valid IP address\n");
}
else
{
printf("The given IP is not a valid IP address\n");
}
}

- 3,338
- 5
- 24
- 45

- 21
- 1
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.

- 4,124
- 4
- 32
- 44
-
1Don't feel bad at all. I was blissfully unaware of a lot of the details mentioned here before I asked this question, including the octal numbers you mentioned. – Bill the Lizard Nov 08 '09 at 00:40
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);
}

- 28,864
- 15
- 75
- 99
-
Not entirely correct, because it doesn't verify that the numbers are in the valid range, but that shouldn't be too hard to fix. – Head Geek Nov 25 '08 at 17:49
-
Actually checking numbers are in a valid range is fairly complicated in regex. See Ferruccio's answer for the corrected regex. – Bill the Lizard Nov 25 '08 at 18:03
-
You could use REGEX to pull out each of the numbers, and then check each set of digits to ensure it's in the proper range. This may be more useful if you want to stop people from entering IPs that can't be accessed from the outside world such as 127.0.0.1 – Kibbee Nov 25 '08 at 18:06
-
As noted in the comment on Ferrucio's regex, you must validate for base 8 and base 16 quads too. – Mihai Limbășan Nov 25 '08 at 19:01
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.

- 7,440
- 8
- 43
- 65
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;
}

- 157
- 1
- 6
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

- 12,245
- 9
- 42
- 49
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.

- 25,272
- 21
- 67
- 103
If you wish to receive an IP address in the usual form (8.8.8.8
, 192.168.1.1
, etc...)
Then I've written the following code that expands on Bjorn's answer:
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");
}
}
The reason being is that if you pass on an IP such as 8.88.8, or 12345 (decimal form), Bjorn's answer won't throw an error. (at least with boost 1.68) My code converts any form to the internal structure in Boost, then converts it back to a dotted-decimal format, we then compare it to the first IP we received to see if they are equal, if not, we know for sure that the input is not the way we wanted it.

- 438
- 2
- 17
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;
}

- 5,996
- 13
- 48
- 61
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);
}
}

- 1