C言語関係掲示板

過去ログ

No.1342 while( fscanf( fp , "%s , %d" , namae , &nenrei ) != EOF )の意味

[戻る] [ホームページ]
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等に答えなければいけない)とか
いろいろな情報が必要なので、このポインタ自体が直接ストリームの
位置になっていることはまずないはずです。