c++ - sscanf 麻烦吗?

标签 c++ c scanf

long ip2long( char *ip )
{
    long ip2long = 0;

    char B1[4], B2[4], B3[4], B4[4];
    int D1, D2, D3, D4 = 0;

    sscanf(ip, "%s.%s.%s.%s", B1, B2, B3, B4);

    D1 = atoi(B1);
    D2 = atoi(B2);
    D3 = atoi(B3);
    D4 = atoi(B4);

    if(D1 > 255 || D2  > 255 || D3 > 255 || D4 > 255)
        return 0;

    ip2long = D1*256*256*256+D2*256*256+D3*256+D4;

    return ip2long;
}

输入数据:127.1.1.2

为什么 D1 == 127,但 D2、D3 和 D4 == 0?

---更新--- 现在代码是

unsigned long ip2long( char *ip )
{
    unsigned long ip2long = 0;
    unsigned int D1, D2, D3, D4 = 0;

    sscanf(ip, "%u.%u.%u.%u", &D1, &D2, &D3, &D4);

    if(D1 > 255 || D2  > 255 || D3 > 255 || D4 > 255)
        return 0;

    ip2long = D1*256*256*256+D2*256*256+D3*256+D4;

    return ip2long;
}

Di 没问题,但还有另一个麻烦:127.1.1.2 的结果是 2130772226 而不是 2130772225,195.98.157.132 的结果是 -1016947324... 为什么?

--- 更新 2 --- 没关系,有 %d 代替 %u。

Kornel Kisielewicz 感谢您介绍 inet_addr 函数:)

PS 抱歉我的英语不好=\

问题已关闭。

最佳答案

正如 fizzer 所指出的,%s 消耗了整个字符串——在这种情况下,危险地将其复制到 S1 的末尾之后。如果将 sscanf() 结果与 4 进行比较,就会有很大的线索!不要假设事情会起作用,尤其是在解析来自程序外部的输入时。 atoi 忽略尾随的垃圾,因此即使使用 %[^.] 字符串格式,它会在一段时间内停止,它也会处理像 192,3.2x 这样的垃圾值。 3.1 忽略 ,3x

fizzer 对 ("...%d...", &D1...) 的建议是一个好的开始,但你仍然必须将结果与 4 进行比较,否则无效的字符串如 "你好”只会让 D1、D2、D3 和 D4 保持不变。负值将被接受。请注意,只有 D4 设置为 0 - 其他值不受该行尾随 = 0 的影响,并且可能包含来自堆栈的旧垃圾值,这些值可能会或可能不会通过稍后针对 255 的检查.

总结:

unsigned long ip2ulong(char *ip)
{
    unsigned u1, u2, u3, u4;
    return sscanf(ip, "%u.%u.%u.%u", &u1, &u2, &u3, &u4) == 4 &&
           u1 <= 255 && u2 <= 255 && u3 <= 255 && u4 <= 255
           ? u1*256*256*256 + u2*256*256 + u3*256 + u4 : 0;
} 

关于c++ - sscanf 麻烦吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5268646/

相关文章:

字符数组未使用 %s 打印

通过scanf在C中输入char

c - 如何在 C 中退出 while 循环?

c - 循环重复scanf和printf

c - 将指针传递给 c 中的 strcpy 函数

c - scanf之后的动态内存分配

C++ 错误 : not a member OR multiple definition

c++ - 在新的 C++11 中可以创建可选引用吗?

c++ - 将二维数组传递给函数

c++ - 获取变量以调用函数c++