2007年9月28日金曜日
IPアドレスが取れない

ある本を使ってお勉強中。
サーバとクライアントのプログラムを作って通信(Telnet)テスト。

本のサンプルどおりにコーディングするも…

(略)

struct sockaddr_in from;
char client_address[80];

(略)

sprintf(client_address, "%d.%d.%d.%d", from.sin_addr.S_un.S_un_b.s_b1, from.sin_addr.S_un.S_un_b.s_b2, from.sin_addr.S_un.S_un_b.s_b3,from.sin_addr.S_un.S_un_b.s_b4);

(以下省略)


test.c:173: error: structure に `S_un' という名前のメンバはありません
test.c:174: error: structure に `S_un' という名前のメンバはありません
test.c:175: error: structure に `S_un' という名前のメンバはありません
test.c:176: error: structure に `S_un' という名前のメンバはありません

…という結果に。

/usr/include を検索(find/grep)しても、見つからない…ということは、そもそもIPのとり方がNGだと考えるしかない。

でもって、探してみるとinet_ntoa()という関数があるらしい。

なので、こう書いてみる。
sprintf(client_address, inet_ntoa(from.sin_addr));


$ gcc test.c 
test.c: In function `MainLoop':
test.c:172: 警告: 引数 2 個の `sprintf' を渡しますにより、キャストなしで整数からポインタを作りまし
$


ありゃ。訂正。
sprintf(client_address, "%s", inet_ntoa(from.sin_addr));


$ gcc test.c
$

無事コンパイル完了。

これが正解なのかどうかは知らないけどね。
同じサーバからtelnetしてみたら、127.0.0.1が来たから問題ないかな~と思ったんだけど??



0 コメント | コメントを書く | コメントの表示
2007年9月18日火曜日
math.h関連のコンパイルエラー

引き続きC言語のお勉強中。
ちょっとポインタあたりを検索しつつ、お勉強してみる。

でもって、サンプルを実行中、どーしてもコンパイルエラーになる。

$ gcc -o sample sample.c
/tmp/ccgJ0RxZ.o(.text+0x30): In function `sample':
: undefined reference to `sqrt'
collect2: ld はステータス 1 で終了しました
$


なんだよー、math.hきちんとインクルードしてんのにさぁ。

答えは簡単。
で定義されている関数の本体は全て math ライブラリにあります。したがってこのような関数を用いるには、リンクの際に -lm が必要になるわけです。
The Linux GCC HOWTO - 6.2 ライブラリに尋ねる(sin() はどこにいるの?)

いやはやお恥ずかしい限りです。
だからさ、初心者なんだって、結局は。
きちんと勉強をした方がよさそうだなぁ。

The Linux GCC HOWTO
http://www.linux.or.jp/JF/JFdocs/archive/GCC-HOWTO.html



0 コメント | コメントを書く | コメントの表示
2007年8月28日火曜日
「Linuxプログラミング―例題で学ぶUNIXプログラミング環境のすべて」でお勉強

久しぶりに、Cのお勉強。
僕自身、そんなにまじめに勉強したことがないので、きちんとやらなきゃと思いながら…
でもって、2~3年くらい前に買った本を久しぶりに開いてみた。

当時よりも幾分Cの知識はあるし、ワリとサクサク進む。

しかし…

ところどころ動かないんですけど?

でもって、版元のサイトを調べると、サンプルソースがダウンロードできるね。

改訂後
http://www.sbcr.jp/books/download/art.asp?newsid=1333

改訂前
http://shop.sbcr.jp/isbn/old/1st/linux/index.htm

実行すると画面がクリアされ、中央ほどに簡単なメニューが表示されるというプログラムがある。
サンプルどおりに打ち込んでコンパイル、実行するのだが、一向に画面が変わらない。
入力待ちになる。

ここでENTERとかなにかキー入力をすると、画面がクリアされ、メニューが表示される。そして誤った入力である旨、表示される(メニューとしては、「a」「d」「q」しか許可していないため、先ほど入力した値を受け取って誤りだと出力する)。

でもって改訂版のソースを見ると、

fflush(out);

が追加されている。
※outは出力先(この場合は標準出力)を指す。

こいつが無いせいで画面が切り替わらなかったんだな。

しかもtputsの第3引数用に関数char_to_terminal()というのを設定しているのだが、この引数の型が改訂前後で違う。
改訂前
int char_to_terminal(char char_to_write);

改訂後
int char_to_terminal(int char_to_write);


おーい!
とか思ってたら、このchar_to_terminal()は単純にputcをコールしてるだけ。
よくよく考えてみると、このputcって第1引数(つまりchar_to_terminal()の第1引数)はintなんだよねぇ。
これはすぐに気が付いてもよかったなぁ。

古いOS(もしくはコンパイラ)だったら動くんか?

まぁ、とにかく、これは注意せねばならんね。


 こっちは僕の持っている改訂前。



0 コメント | コメントを書く | コメントの表示
Template Design: © 2007 Envy Inc.