What would be a good way to determine if a string contains an IPv4 address? Should I use isdigit()
?
I asked a similar question for C++. You should be able to use a slightly modified (for C) version of what I came up with back then.
bool isValidIpAddress(char *ipAddress)
{
struct sockaddr_in sa;
int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
return result != 0;
}
You'll need to #include <arpa/inet.h>
to use the inet_pton() function.
Update based on comments to the question: If you want to know if a C-style string contains an IP address, then you should combine the two answers given so far. Use a regular expression to find patterns that roughly match an IP address, then use the function above to check the match to see if it's the real deal.
This is a routine I wrote a while ago for an embedded system which generated various suspect patterns on a network. As such, it uses absolutely no fancy stuff like network libraries or even the standard C libraries, preferring to steer clear of all that modern stuff like string tokenizing and (shudder) regular expression libraries :-) To that end, it's suited to just about any environment you could find yourself in, and it was blindingly fast.
Although, if you're in an environment that has something like checkIp4Addess()
, I'd suggest you use that instead. It's an indication of the stuff you sometimes have to put up with when doing embedded stuff (although it is a real solution).
int isValidIp4 (char *str) {
int segs = 0; /* Segment count. */
int chcnt = 0; /* Character count within segment. */
int accum = 0; /* Accumulator for segment. */
/* Catch NULL pointer. */
if (str == NULL)
return 0;
/* Process every character in string. */
while (*str != '\0') {
/* Segment changeover. */
if (*str == '.') {
/* Must have some digits in segment. */
if (chcnt == 0)
return 0;
/* Limit number of segments. */
if (++segs == 4)
return 0;
/* Reset segment values and restart loop. */
chcnt = accum = 0;
str++;
continue;
}
/* Check numeric. */
if ((*str < '0') || (*str > '9'))
return 0;
/* Accumulate and check segment. */
if ((accum = accum * 10 + *str - '0') > 255)
return 0;
/* Advance other segment specific stuff and continue loop. */
chcnt++;
str++;
}
/* Check enough segments and enough characters in last segment. */
if (segs != 3)
return 0;
if (chcnt == 0)
return 0;
/* Address okay. */
return 1;
}
It works on the dotted decimal address representation (four segments) but, since this pretty much the most common form by far, I don't consider that much of a limitation. There were other representations long ago (that are probably still valid) but it's rare to see them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With