确定字符串是否是C中的有效IPv4地址

25 c string

确定字符串是否包含IPv4地址的好方法是什么?我应该用isdigit()吗?

Bil*_*ard 54

我问过类似的C++问题.您应该能够使用我当时提出的稍微修改过的(对于C)版本.

bool isValidIpAddress(char *ipAddress)
{
    struct sockaddr_in sa;
    int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
    return result != 0;
}
Run Code Online (Sandbox Code Playgroud)

您需要#include <arpa/inet.h>使用inet_pton()函数.

根据对问题的评论进行更新:如果您想知道C风格的字符串是否包含 IP地址,那么您应该结合到目前为止给出的两个答案.使用正则表达式查找与IP地址大致匹配的模式,然后使用上面的函数检查匹配项以查看它是否真实.

  • @ NehalJ.Wani"localhost"是主机名,而不是IP地址. (4认同)
  • 警告:此答案不兼容IPv6! (2认同)
  • `inet_pton`可能会在出错时返回`-1`.你的测试应该是`result == 1`或者至少是`result> 0` (2认同)
  • inet_pton() 成功返回 1(网络地址已成功转换)。如果 src 不包含表示指定地址族中有效网络地址的字符串,则返回 0。如果 af 不包含有效的地址族,则返回 -1 并将 errno 设置为 EAFNOSUPPORT。 (2认同)

pax*_*blo 8

这是我不久前写的一个嵌入式系统的例程,它在网络上生成了各种可疑模式.因此,它绝对使用像网络库甚至标准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;
}
Run Code Online (Sandbox Code Playgroud)

 

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的观点 - 我认为我们将其用于阻止像192.1.004.1这样的事情.要么客户非常幸运,要么因为错误而停止使用我们的代码:-).我会解决它. (2认同)

mas*_*oud 5

int validate_ip4(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;

    char tmp[16];
    snprintf(tmp, 16, "%u.%u.%u.%u", d[0], d[1], d[2], d[3]);
    if (strcmp(s, tmp) != 0)
        return 0;

    return 1;
}
Run Code Online (Sandbox Code Playgroud)