簡體   English   中英

inet_ntoa的奇怪printf行為

[英]Weird printf behaviour with inet_ntoa

#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;
}

為什么首先pritnf打印兩次相同的IP,而不是給出兩次? 第二和第三似乎還可以。 似乎在Linux gcc / clang和freebsd clang上發生過,這是已知的嗎?

inet_ntoa的手冊頁中:

inet_ntoa()函數inet_ntoa()網絡字節順序給定的Internet主機地址轉換為標准的數字符號形式的字符串。 該字符串在靜態分配的緩沖區中返回,后續調用將覆蓋該緩沖區。

由於inet_ntoa將靜態緩沖區用於其輸出,並且由於您在一個函數調用中兩次調用了它,所以printf傳遞了相同指針的兩個副本。 它包含最后一次調用的內容。

您需要像下面幾行那樣將打印分為兩個單獨的調用。

看一下inet_ntoa的POSIX文檔,特別是“應用程序用法”部分:

inet_ntoa()的返回值可能指向靜態數據,該靜態數據可能會被隨后inet_ntoa() 調用覆蓋

這就是這里發生的情況:第一個printf中的兩個調用之一正在覆蓋另一個調用(並且您不知道哪個-函數參數的求值順序是實現定義的)。

因此,要么堅持使用兩個printfs,要么將inet_ntoa返回的字符串復制到您自己的緩沖區中,然后進行打印。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM