inet_ntoa 的奇怪 printf 行为

seu*_*nje 3 c sockets printf

#include <sys/socket.h>
#include <err.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(int argc, char **argv) {

    struct sockaddr_in X = {0};
    X.sin_family = AF_INET;
    X.sin_addr.s_addr = inet_addr("127.0.0.1");
    X.sin_port = htons(8080);

    struct sockaddr_in Y = {0};
    Y.sin_family = AF_INET;
    Y.sin_addr.s_addr = inet_addr("212.43.159.20");
    Y.sin_port = htons(80);

    printf("X:Y %s:%s\n", inet_ntoa(X.sin_addr), inet_ntoa(Y.sin_addr));
    printf("X %s\n", inet_ntoa(X.sin_addr));
    printf("Y %s\n", inet_ntoa(Y.sin_addr));

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

为什么首先 pritnf 打印相同的 IP 两次而不是给出的内容?第二个和第三个好像没问题。似乎发生在 linux gcc/clang 和 freebsd clang 上,这是已知的吗?

dbu*_*ush 5

从手册页inet_ntoa

inet_ntoa()函数将网络字节顺序中给定的 Internet 主机地址转换为标准数字和点表示法的字符串。该字符串在静态分配的缓冲区中返回,后续调用将覆盖该缓冲区。

由于inet_ntoa使用静态缓冲区作为其输出,并且因为您在一次函数调用中调用它两次,因此printf传递了同一指针的两个副本。它包含最后完成的调用的内容。

您需要将打印拆分为两个单独的调用,就像您在以下几行中所做的那样。