C++についても同様の質問をしました。当時私が思いついたものを少し変更した (C 用の) バージョンを使用できるはずです。
bool isValidIpAddress(char *ipAddress)
{
struct sockaddr_in sa;
int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
return result != 0;
}
#include <arpa/inet.h>
する必要があります inet_pton() 関数を使用します。
質問へのコメントに基づいて更新:C スタイルの文字列 contains かどうかを知りたい場合 IP アドレスの場合は、これまでに与えられた 2 つの回答を組み合わせる必要があります。正規表現を使用して IP アドレスに大まかに一致するパターンを見つけてから、上記の関数を使用して一致をチェックし、それが本物かどうかを確認してください。
これは、ネットワーク上でさまざまな疑わしいパターンを生成する組み込みシステム用に、少し前に作成したルーチンです。そのため、絶対に no を使用します ネットワーク ライブラリや標準の C ライブラリなどの凝ったものでさえ、文字列のトークン化や (身震いする) 正規表現ライブラリなどの最新のものをすべて避けることを好みます :-) そのために、それはあなたが自分自身を見つけることができるほぼすべての環境に適しています、目がくらむほど速かったです。
ただし、 checkIp4Addess()
のような環境にいる場合 、代わりにそれを使用することをお勧めします。これは、組み込み作業を行うときに時々我慢しなければならないことを示しています (ただし、 本当の解決策)。
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;
}
int validateIP4Dotted(const char *s)
{
int len = strlen(s);
if (len < 7 || len > 15)
return 0;
char tail[16];
tail[0] = 0;
unsigned int d[4];
int c = sscanf(s, "%3u.%3u.%3u.%3u%s", &d[0], &d[1], &d[2], &d[3], tail);
if (c != 4 || tail[0])
return 0;
for (int i = 0; i < 4; i++)
if (d[i] > 255)
return 0;
return 1;
}