7

inet_atonネットワークアドレスの変換に問題があります。以下のコードは、アドレスを変換するために正常に機能します10.0.0.1

char *x1;
struct sockaddr_in si_other;
inet_aton("10.0.0.1", &si_other.sin_addr);
printf("si_other.sin_addr =%lu\n",si_other.sin_addr);
x1 = inet_ntoa(si_other.sin_addr);
printf("x1=%s\n",x1);

以下を出力します。

si_other.sin_addr =16777226
x1=10.0.0.01

今のところ問題ありません。010.000.000.001ただし、渡されると関数は奇妙に動作します

char *x2;
struct sockaddr_in si_other2;
inet_aton("010.000.000.001", &si_other2.sin_addr);
printf("si_other2.sin_addr =%lu\n",si_other2.sin_addr);
x2 = inet_ntoa(si_other2.sin_addr);
printf("x2=%s\n",x2);

出力:

si_other.sin_addr2 =16777224
x2=8.0.0.01

この関数は、192.168.0.1192.168.000.001が渡されると正常に機能します。

誰かが私に問題とは何か、そして私が問題を解決する方法を説明できますか?(注:010.000.000.001コードのようにIPアドレスを渡す必要があります)

4

1 に答える 1

12

先頭の0は、数値が8進数であることを示していると解釈されています。010(oct)== 8(dec)。これを回避するために入力を変更するinet_atonか、別の方法で自分で変換する必要があります。

const char *str = "010.000.000.001";
inet_aton(str[0] == '0' ? str+1:str, &si_other.sin_addr);

最も簡単な解決策ですがsnprintf、混乱を避けるために、最初に文字列を生成するもの(?)を修正することをお勧めします。

(現状では、「001.0.0.1」、「0xF.0.0.1」、「1」、その他多くの有効なIPv4アドレスを含む、多くのエッジケースではソリューションは機能しません)。

sscanfそもそも入力の生成方法を制御できない場合でも、を使用して入力を簡単に「正規化」できます(ただし、私の見解では、これは実際にはバグであるはずです)。

#include <stdio.h>
#include <stdlib.h>

int main() {
  const char *str="010.020.030.040";
  int parts[4];
  sscanf(str, "%d.%d.%d.%d", parts+0, parts+1, parts+2, parts+3);
  char *out = NULL;
  asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
  printf("%s\n", out);
  free(out);
  return 0;
}
于 2013-01-06T22:35:07.227 に答える