6

ホスト名と IP アドレスを取得するための次のコードがあります。

#include <stdlib.h>
#include <stdio.h>
#include <netdb.h> /* This is the header file needed for gethostbyname() */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


int main(int argc, char *argv[])
{
struct hostent *he;

if (argc!=2){
printf("Usage: %s <hostname>\n",argv[0]);
exit(-1);
}

if ((he=gethostbyname(argv[1]))==NULL){
printf("gethostbyname() error\n");
exit(-1);
}

printf("Hostname : %s\n",he->h_name); /* prints the hostname */
printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr))); /* prints IP address */
}

しかし、コンパイル中に警告が表示されます:

$cc host.c -o host
host.c: In function ‘main’:
host.c:24: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’

次に、コードを実行するとセグメンテーション エラーが発生します。

./host 192.168.1.4
Hostname : 192.168.1.4
Segmentation fault

コードのエラーは何ですか?

4

5 に答える 5

8

私は似たようなコード (同じではないにしても) を持っていて、学校の実験室のマシンで問題なくコンパイルできましたが、自宅のマシンでコンパイルすると同じエラーが発生しました (コードを編集しませんでした)。のマニュアル ページを読んだinetところ、ヘッダー ファイルが 1 つ不足していることがわかりました#include <arpa/inet.h>。そのヘッダーを C プログラムに追加した後、コンパイルして正常に実行されました。

于 2011-09-22T18:48:04.497 に答える
6

printf フォーマットの不一致に関する警告は、重要な警告です。inet_ntoaこの場合、関数が を返すとコンパイラが考えているために発生しintますが、format-string で文字列を期待するように指定しました。

誤った戻り値の型inet_ntoaは、以前の宣言なしで関数を使用しようとすると、コンパイラは関数が を返し、int不明な (ただし固定の) 数の引数を取ると見なす必要があるという古い C 規則の結果です。想定される戻り値の型と関数の実際の戻り値の型が一致しないと、未定義の動作が発生し、ケースではクラッシュとして現れます。

解決策は、 の正しいヘッダーを含めることですinet_ntoa

于 2010-08-25T15:37:15.800 に答える
1

このコードを破る:

printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr)));

これに:

struct in_addr* address = (in_addr*) he->h_addr;
char* ip_address = inet_ntoa(*address);
printf("IP address: %s\n", ip_address);

また、問題のデバッグと特定が容易になります。

于 2010-09-12T14:18:22.427 に答える
0

he->h_addrの値を逆参照してに渡す前に、の値をダンプしてみてくださいinet_ntoa。もしそうならNULL、それはセグメンテーション違反になります。

それを実行してみstraceませんか?

于 2010-05-25T20:11:38.390 に答える
0

実際、自宅の FreeBSD マシンでそのコードをコンパイルしたところ、動作しました。

于 2010-05-25T17:34:57.640 に答える