如何使用 fscanf 扫描 IP 地址

Ste*_*fan 2 c ip scanf

如何在c中使用scanf扫描IP地址?

我已经用户:

scanf(" %d ", &ip_adress)

我应该使用

%d.%d.%d

或者有更简单的方法。

这是我从文件中读取信息的函数:

void read_tree_from(FILE *in, PC **root){
    char name[MAX_NAME];
    int ip_adress;
    int speed;
    while(fscanf(in, "%s %d %d", name, &ip_adress, &speed) != EOF){
        PC *new = create_new_item(name, ip_adress, speed);
        add_to_tree(new, root);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行该程序时,它工作正常,但在输出文件中却很混乱......

Ste*_*ner 5

您可以使用格式说明符%hhu.%hhu.%hhu.%hhu,它读取无符号的 8 位值,并且您可以分别直接读取 ip 地址的 int 表示的 4 个字节:

int main () {

    const char* testLine = "aName 192.168.112.54 100";

    char name[100];
    int speed;

    volatile uint32_t ipAddress=0;
    unsigned char* ipAddressBytes = (unsigned char*)&ipAddress;


    if (sscanf(testLine, "%s %hhu.%hhu.%hhu.%hhu %d", name, ipAddressBytes+3, ipAddressBytes+2,ipAddressBytes+1,ipAddressBytes+0, &speed) == 6) {
        printf("%s %08X %d\n",name, ipAddress, speed);
    }

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

输出:

aName C0A87036 100
Run Code Online (Sandbox Code Playgroud)

Format%hhu读入一个整数值并将其映射为8位;因此,它不会检查有关 IP 地址的输入是否有效(即1025.168.112.54无效)。然而,它避免了技术溢出,因为任何超过 8 位的部分都会被忽略。所以之前提到的输入会产生01A87036

请注意volatile- 说明符,它告诉编译器不应优化对此变量的访问;否则,编译器可能会假设 - 由于值没有明显更改 - 变量未更改/未初始化。

进一步注意,您必须注意您的环境是大端还是小端架构。

希望能帮助到你。