No.18214![]() |
ライブラリ関数のファイル操作について 投稿者---真っ赤な帽子(2004/11/18 01:10:49) |
||
初めまして、みなさん。 私は Red Hat Linux 7J の GCC でC言語を独習している者です。 今、私は、某参考書でライブラリ関数のファイル操作について勉 強しているのですが、例題で少しわからないところがあるので質 問させてください。 例題のプログラムは以下の通りです。 【プログラム】 #include <stdio.h> main() { char namae[10]; int nenrei; FILE *fp; if ( ( fp = fopen( "REI.IN" , "r" ) ) == NULL ) { printf( "can't open\n" ); } else { while( fscanf( fp , "%s , %d" , namae , &nenrei ) != EOF ) { printf( "%20s %dyears old.\n" , namae , nenrei ); } fclose( fp ); } } 【REI.INの内容】 【実行結果】 yamamoto-naoko , 20 yamamoto-naoko 20years old. sato-toshiro , 18 sato-toshiro 18years old. takahashi-hideya , 22 takahashi-hideya 22years old. このプログラムで私が知りたいのは、下線で示しているfscanf関 数をwhileでループさせているところです。 この例題でfscanf関数は、fpが指すストリームからの入力を指定 された書式("%s , %d")に変換し、続く実引数( namae , &nenrei ) が指すオブジェクトに代入しているのだと思います。 一回目でREI.INの「yamamoto-naoko , 20」を指定書式に変換 しているのはわかりますが、2回目で「yamamoto-naoko , 20」 ではなく、どうして「sato-toshiro , 18」を変換している のかがわかりません。 2回目でfpが指すFILE構造体がストリームを制御して「sato-toshi ro , 18」を渡しているのだとは思いますが、FILE構造体の構造 (メンバ)がどういうものかわからないので、上記のように納得が いかなくなってしまいます。 私が使っている某参考書には、 「構造体FILEはヘッダstdio.hに定義されている構造体であり、スト リームを制御する情報を含む」 としか書かれていませんでした。 これだけではちょっとわからないので、私は「 FILE構造体は構造体 型配列であり、REI.INの一行分のデータを各配列に格納している 」 と考えました。しかし、それでは例題の「 fp 」は、インクリメント されていないし、変だなと混乱してしまいました。 頭の中が無限ループに陥ってますので、どなたかFILE構造体について 教えてくださいませ。 かしこ |
No.18215![]() |
Re:ライブラリ関数のファイル操作について 投稿者---Ban(2004/11/18 01:46:00) |
||
> これだけではちょっとわからないので、私は「 FILE構造体は構造体 > 型配列であり、REI.INの一行分のデータを各配列に格納している 」 > と考えました。しかし、それでは例題の「 fp 」は、インクリメント > されていないし、変だなと混乱してしまいました。 > 頭の中が無限ループに陥ってますので、どなたかFILE構造体について > 教えてくださいませ。 まず、配列ではありません。あくまでひとつの構造体だと思ってください。 で、中に何が書いてあるか、具体的な内容は知らなくても使えるように なっているので、コンパイラごとにばらばらですが、大抵 「今の読み出し/書き込み位置」という情報がはいってます。 (ftell/fseel 関数などで直接制御もできます) ファイルから10文字読んだら、FILE 内の「位置」情報も 10文字分進められているので、次の読み出しはそちらから 行われます。このため連続して読み出すと次々と先の情報が 取れるようになっています。 また、あくまで「ファイルに関する情報」が入っているもので、 ファイルの内容自体は普通入っていません。 |
No.18216![]() |
Re:ライブラリ関数のファイル操作について 投稿者---Ban(2004/11/18 01:53:46) |
||
>(ftell/fseel 関数などで直接制御もできます) 訂正。fseel -> fseek |
No.18237![]() |
Re:ライブラリ関数のファイル操作について 投稿者---真っ赤な帽子(2004/11/19 00:44:27) |
||
banさん、レスありがとうございます。早速、読ませて頂きました。 >まず、配列ではありません。あくまでひとつの構造体だと思ってください。 ふむふむ。 >で、中に何が書いてあるか、具体的な内容は知らなくても使えるように >なっているので、コンパイラごとにばらばらですが、大抵 >「今の読み出し/書き込み位置」という情報がはいってます。 「今の読み出し/書き込み位置」情報ですか! くだらないかもしれませんが、 かなり驚きました。 具体的な内容はコンパイラごとにバラバラである為、あえて 記載されてなかったわけですね。 >(ftell/fseek 関数などで直接制御もできます) 確かに私の参考書にも、もう少し先にftell , fseek関数が載っていますね。 取り掛かっている項目が終わったら、ゆっくり熟読してみたいと思います。 >ファイルから10文字読んだら、FILE 内の「位置」情報も >10文字分進められているので、次の読み出しはそちらから >行われます。このため連続して読み出すと次々と先の情報が >取れるようになっています。 「位置」情報ということは、FILEの中身はストリームの位置を指すポインタ ということになるのでしょうか。大変、興味があります。 >また、あくまで「ファイルに関する情報」が入っているもので、 >ファイルの内容自体は普通入っていません。 ここまで読むと、ストリームを制御するというのも頷けますね。私は、当初 「ファイルの内容」が入っていると思っていたので、位置情報が入っている ということには驚きました。実際に中身をみれ無かったのは残念ですが、 大変、有益な情報をいただけましたbanさんには感謝をしております。 banさんどうもありがとうございました。 |
No.18240![]() |
Re:ライブラリ関数のファイル操作について 投稿者---Ban(2004/11/19 03:09:25) |
||
>「位置」情報ということは、FILEの中身はストリームの位置を指すポインタ >ということになるのでしょうか。大変、興味があります。 普通の実装だと、ストリームの位置を示す情報「も」FILE の中に 入ってますが、それがポインタとは限りません。先頭からのバイト数 かも知れませんし、もっと違うかもしれません。 前述のように、具体例はライブラリを書いた人の設計によります。 # 仮に私が書くなら多分先頭からのバイト数にすると思います。 ただ、FILE 自体には位置の他にも例えばディスクリプタ(「低水準I/O」 で使う)とか、今の状態(ferror/feof等に答えなければいけない)とか いろいろな情報が必要なので、このポインタ自体が直接ストリームの 位置になっていることはまずないはずです。 |