如何在 C++ 中验证字符串是否是有效的 IPv4 地址?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/318236/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you validate that a string is a valid IPv4 address in C++?
提问by Bill the Lizard
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.
我不需要验证 IP 地址是否可访问或类似的东西。我只想验证字符串是否为点分四 (xxx.xxx.xxx.xxx) IPv4 格式,其中 xxx 介于 0 和 255 之间。
回答by Raymond Martineau
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.
您可能需要inet_pton,它为无效 AF 参数返回 -1,为无效地址返回 0,为有效 IP 地址返回 +1。它支持 IPv4 和未来的 IPv6 地址。如果您仍然需要编写自己的 IP 地址处理,请记住标准的 32 位十六进制数是有效的 IP 地址。并非所有 IPv4 地址都采用点分十进制表示法。
This function both verifies the address, and also allows you to use the same address in related socket calls.
此函数既验证地址,也允许您在相关的套接字调用中使用相同的地址。
回答by Bj?rn Pollex
Boost.Asioprovides the class ip::address. If you just want to verify the string, you can use it like this:
Boost.Asio提供了类ip::address。如果你只是想验证字符串,你可以像这样使用它:
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.
这也适用于十六进制和八进制四边形。这也是一个更便携的解决方案。
回答by Bill the Lizard
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.
这适用于其他答案中提到的大多数情况。它无法识别八进制或十六进制格式的 IP 地址,但这对我的应用程序来说是可以接受的。
回答by Mihai Limb??an
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 mustbe 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 not192.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.
这看起来看似简单,但有一些陷阱。例如,在之前的答案中发布的许多解决方案都假设四边形以 10 为基数 - 但是以零开头的四边形必须被视为以 8 为底的(八进制)数,因此例如任何以零开头的四边形部分和包含数字 8 或 9 是无效的。即IP号192.168.1.010
是不是192.168.1.10
,但现实是192.168.1.8
,和IP号码192.168.019.14
,因为第三个四倍包含无效基地8位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.)
编辑:(认为这是隐含的,但是)当然,您也可以使用十六进制四边形,la192.168.1.0x0A
表示 192.168.1.10,当然您可以使用大小写愉快地混合和匹配您的虐待狂内容,la0xC0.0xa8.1.010
表示 192.168 .1.8. 如果您想玩得开心,请尝试使用 ping 的一些示例。这在跨平台上工作得很好(在 Linux、NetBSD 和 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:
进一步编辑以响应 KaluSingh Gabbar 的请求:例如,您可以指定192.168.1.10
as0xc0a8010a
并且它仍然代表一个有效的 IP 号码,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
回答by Steve
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;
}
回答by user1740538
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.
如果您在 Windows 上,您可以使用WSAStringToAddress
并基于我们知道的返回值,无论传递的参数是否是有效的 IP。这从 Windows 2000 开始支持 IPv4 和 IPv6。
回答by Ramadheer Singh
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.
我只使用 C stdlib 函数做了同样的事情,虽然它不支持上述八进制四边形,但这应该不是问题,我可以轻松添加该部分并将其提供给您。作为初学者(学生),直到现在我都不知道可以在您的 ip 中获得一个八进制数。我认为它必须是一个小数。
回答by Kim Ninh
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. :))
sscanf()
并且sprintf()
在某些情况下非常有用。:))
回答by Savi
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.
这是验证给定 IPV4 地址的 C 程序。我假设 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]!='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);
}
')
{
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");
}
}
回答by Martin Cote
Boost.Regexwould be appropriate.
Boost.Regex将是合适的。
##代码##