如何validation一个string是C ++中的有效IPv4地址?

我不需要validationIP地址是否可达或类似的东西。 我只想validation该string是否为点分布式(xxx.xxx.xxx.xxx)IPv4格式,其中xxx在0和255之间。

您可能需要inet_pton ,对于无效的AF参数返回-1,对于无效的地址返回0,对有效的IP地址返回+1。 它支持IPv4和未来的IPv6地址。 如果仍然需要编写自己的IP地址处理,请记住标准的32位hex数是有效的IP地址。 并不是所有的IPv4地址都是点分十进制的。

此函数既validation地址,也允许您在相关套接字调用中使用相同的地址。

Boost.Asio提供了类ip :: address 。 如果你只是想validationstring,你可以像这样使用它:

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; 

这也适用于hex和八进制四边形。 这也是一个更便携的解决scheme。

我解决的解决scheme是:

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

这适用于其他答案中提到的大多数情况。 它不能识别八进制或hex格式的IP地址,但这对我的应用程序是可以接受的。

这看起来很简单,但有一些缺陷。 例如,在前面的答案中发布的许多解决scheme都假定四边形是以10为底的 – 但是以零开始的四边形必须被视为基8(八进制)数,因此例如任何以零开始的四边形部分和包含数字8或9是无效的。 也就是说,IP号码192.168.1.010 不是 192.168.1.10但实际上是192.168.1.8 ,而IP号码192.168.019.14是无效的,因为第三个四元组包含无效的基数8位9。

我强烈build议您使用操作系统或编译器环境中包含的套接字库提供的函数。

编辑:(当然是隐含的,但是)你也可以有hex的四元组, 192.168.1.0x0A为192.168.1.10,当然你可以用大写和小写的快乐地混合你的虐待内容,一个la 0xC0.0xa8.1.010为192.168.1.8。 如果你想获得乐趣,可以使用ping来尝试一些例子。 这工作很好跨平台(在Linux,NetBSD和Win32下骂了一阵子)。

进一步编辑以响应KaluSingh Gabbar的请求:例如,您可以指定192.168.1.100xc0a8010a ,它仍然表示一个有效的IP号码,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 

这是一个简单的方法。

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

如果你在windows上,你可以使用WSAStringToAddress并根据我们知道的返回值,如果传递的参数是有效的IP或不。 这从Windows 2000开始支持IPv4和IPv6。

如果你想自己写这个,而不是使用一个库

atoi()将字符转换为整数将允许您testing每个数字的范围,以及“。”之间的一些strcmp。 你也可以做一些快速检查,比如string的长度(应该less于16个字符(不包括空终止符),点数等。

但是,使用现有的代码可能会更容易。

这是C程序来validation一个给定的IPV4地址。 我假定IP地址是十进制格式。 请给我你的想法。

  // 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 nnnn 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"); } } 

我只使用C stdlib函数完成了相同的操作,虽然它不支持上面提到的八进制四元组,但是这不应该是一个问题,我可以轻松地添加该部分并将其提供给您。 作为一个初学者(学生),我甚至不知道,直到现在可以在你的ip中获得一个八进制数。 我以为它一定是小数。

Boost.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); } 

使用boost tokenizer和boost char_separator可以很容易地完成这个任务。

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

如果您不想要Boost或TR1的开销,您可以search点,并检查它们之间的字符是否是从0到255的数字。

一些小的修复,修复一些情况下127..0.1,127.0.0 ..并删除空格,如果有:

 #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, eg 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; } 
 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; }