去年の今ごろより少し前に書いていたメモから.
Cでファイルをオープンして,1文字ずつ読み出すという処理を書くとき,普通は,fopenで開き,fgetcで
c = fgetc(fp);
と書きます.ここでcはint型の変数として,あらかじめ宣言しておきます.もしchar型で宣言すると,関数の戻り値がEOFだったときにトラブルのもとです.
2年後期の演習で,ソケット通信の前提としてin the runup to the communication programming using socket,低水準入出力を学んでもらっています.低水準入出力では,openで開き,readで
read(fd, &c, 1);
のように書けばいいでしょう.実際にはセミコロンを書かず,この戻り値を使って,読み出せたか,ファイルの末尾になっていないかを判定します.
ここの変数cは,int型ではなくchar型にします.
去年,cをint型にしていて,「while (c != '\n')」と書いていたため,無限に抜けられないという失敗をしてしまいました.関数の中でcを定義していたので,auto変数となり,0でない不定値が格納されていました.上のようなread関数の呼び出しでは,変数cの中の1バイトだけが変更されるので,そこに'\n'が格納されても,残りのバイトがすべて0でない限り,「c != '\n'」が常に真になってしまった,という次第です.
関連情報:
- http://www.linux.or.jp/JM/html/LDP_man-pages/man3/gets.3.html:この中に,fgetcの説明があります.適当なLinuxマシンで「man fgetc」を実行しても,同じように,タイトルはGETSですね.
- http://www.linux.or.jp/JM/html/LDP_man-pages/man2/read.2.html
- C言語関係掲示板 過去ログ1246:ssize_t と size_t の二つの型がどのように宣言されているかが書かれています.ssize_tというのは,read関数の戻り値の型なのですが,負の数を取り得るということで,size_tとまったく異なる型になることが(GCCという処理系の例である点には注意しつつも)分かりました.