2

2つの文字列でprintf/printf_sを使用すると、両方の%s変数で同じ出力が得られます。

IN_ADDR oldIP;
oldIP.S_un.S_addr = iptable[j]->ipAddress;
IN_ADDR newIP;
newIP.S_un.S_addr = adapterTbl->table[i].dwAddr;
printf_s("index %d old: %s new: %s", 
          adapterTbl->table[i].dwIndex, inet_ntoa(oldIP),
           inet_ntoa(newIP));

出力は次のとおりです。

index 11 old: 192.168.1.1 new: 192.168.1.1

ここで、printステートメントの前にブレークしてoldipとnewipの値が異なることを確認しました。また、次の関数を作成して、(inet_ntoaの代わりに)printステートメントで使用しようとしました。

char *convertIP (DWORD ip)  
{  
    IN_ADDR *addr = new IN_ADDR;
    memset(addr, 0, sizeof(IN_ADDR));
    addr->S_un.S_addr = (u_long) ip;
    return inet_ntoa(*addr);
} 

これによる出力は次のとおりです。

192.168.1.1
192.168.1.2
index 11 old: 192.168.1.1 new: 192.168.1.1

なぜこの動作が見られるのですか?どうすれば修正できますか?
ありがとう :)

4

2 に答える 2

6

inet_ntoaretuns:

静的に割り当てられたバッファ。後続の呼び出しで上書きされます

(これはLinuxのマンページからのものです。)

関数で2回使用することはできません。2番目の呼び出しの出力のみが表示されます(2つの呼び出しのどちらが2番目であるかはわかりません。関数の引数の評価順序は指定されていません)。

2つの別々のを実行するか、の出力をローカルバッファにprintfコピーして、それらを出力します。inet_ntoa

POSIXから:

inet_ntoa ()の戻り値は、後続のinet_ntoa ()の呼び出しによって上書きされる可能性のある静的データを指している可能性があります。

したがって、この動作はおそらくLinuxに限定されるものではなく、静的バッファを上書きしないことを信頼することはできません。

于 2012-04-03T20:07:34.020 に答える
1

Mat が説明した理由によりinet_ntoa、次の呼び出しを実行する前に、1 つの呼び出しの結果を使用する必要があります。

これを行う簡単な方法の 1 つを次に示します。

IN_ADDR oldIP;
oldIP.S_un.S_addr = iptable[j]->ipAddress;
IN_ADDR newIP;
newIP.S_un.S_addr = adapterTbl->table[i].dwAddr;
std::string s_old(inet_ntoa(oldIP));
std::string s_new(inet_ntoa(newIP));
printf_s("index %d old: %s new: %s", 
      adapterTbl->table[i].dwIndex, s_old.c_str(),
       s_new.c_str());

stringコンストラクターは、渡された C 文字列のコピーを作成することに注意してください。したがって、inet_ntoaが再度呼び出されると、以前に保存された値を自由に上書きできます。

于 2012-04-03T20:20:27.133 に答える