- ベストアンサー
独習Cのファイル入出力について
- 独習Cで勉強しているが、ファイルの入出力についてわからない点が多い。
- fopen関数を使い、ファイルを開くことができるが、なぜファイル型の宣言が必要なのか疑問である。
- また、FILE型について理解ができていない。教科書の紹介もお願いしたい。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
私自身100%の独学者なので、これらの疑問はよくわかります。若干無理やりなところ(正確ではない表現)はありますが、以下のように考えてみては如何でしょうか。 1) fopen は関数です。関数には、関数の名、引数、戻り値がセットになります。そこで、関数プロトタイプを、以下のように若干書き換えました。 FILE* fopen(char*, char*); 単に、fopen の頭の"*" を FILE の側に付け替えた違いしかありませんが、意味は同じです。 関数名の前にあるのは戻り値の型名ですので、fopen の戻り値は、FILE* ということになり、これは「 FILE 構造体型へのポインタを返す」ことを意味しています。 2) fopen は、管理するファイルの様々な情報を返す関数で、その入れ物が FILE 構造体(へのポインタ)でもあります。単にファイルを開く行為は、fp という変数は必要ありませんが、正しく動作しているかどうか確かめておかないと、その後の操作が怪しくなります。それを確かめるのが if(fp == NULL){...} です。ファイルを開くことに失敗すると、fopen は NULL という値を返すのです。 なお、ここで、if(fopen(...) == NULL){...}ではどうしてダメなのかという問題がありますが 4)で後述します。 3) FILE 型の定義は、stdio.h で定義されていますが、入れ物たる変数の宣言は、ユーザーが用意する必要があります。それが fp です。 ここでもやはり、 FILE *fp; と FILE* fp; は同じことで、fp は FILE 構造体のポインタ変数になります。 4) ファイル操作の場合、ファイルが正しく開けたかどうか、ファイルが開いた状態(アクセス出来る状態)かどうか等の状態を操作前に確かめる必要があります。そこで役立つのが fp です。以後、このコードでは対象となるファイルへのアクセスは fp を使って行うのです。 fopen はファイルを開く動作を行いますが、その状態を保持することは出来ません。関数は、その一文を終えると、返す(戻り)値も消えてしまうからです。そのため、fp に保存しておくわけです。 なお、fp = fopen(...); if(fp == NULL){...} をまとめた一文が if((fp = fopen(...)) == NULL){} になります。 5) 最後に、ファイルへの様々な情報を保持する FILE 構造体へのイメージですが、簡単に言えば接続中のファイルかどうかが分かる情報を持っていると考えると良いのではないでしょうか。 構造体なので、複数の情報(型や値)を持っていますが、現状でその中身を知ろうとするとハマります。とりあえず、開いたファイルの身代わりになる便利な変数として捉えましょう。 6) 補足:関数名の頭に * が付くケースとして、関数ポインタ (*function)(type...) というものがありますので、後々注意しましょう。 7) ポインタに関しては紙面が足りませんが、本体かそのアドレスかの違い程度で今は良いのでは。 8) 良書は沢山あると思いますが、一長一短です。まずその独習Cを一通り読んでみてから(分からなければ飛ばす)、別書を手に取る方が結局速い習得方法かも知れません。その際、分からない、曖昧な点に印を付しておくことです。同書内で解決出来る場合もあれば、他書に頼らざる得ないケースも出て来ます。
その他の回答 (3)
- admiral_ya
- ベストアンサー率56% (110/193)
実際の回答は既に他の方が書かれているので、読んでいて思った事を述べさせてもらいます。 書かれた内容から察すると、「独習C」の該当箇所に至る部分までの内容を消化し切れていない気がします。もし消化できていれば、 > ファイルを開くときはfopenを使うとあり、下記の説明があります。 > FILE *fopen(char *ファイル名, char *モード) と書きつつ、 > fopenはポインタなのでしょうか。stdio,hを使えば良いとあるのに、なぜファイル型の宣言をしなければならないのでしょうか。また例題ではfopenはファイル型として宣言していませんがなぜこれでよいのでしょうか。 という質問、表現はしないので。 この様な時の対処は 2 つだと思います。 (1) ここまでの内容を読み直し、 * #include が何を意味するのか? * 関数とは何? * 型とは? あたりをしっかり復習・把握する (2) 取り敢えず、解らない箇所は付箋でも付けて、そのままスルーする 業務で使う場合、これは許されませんが、「独習」して、趣味としてなら問題ないでしょう 私は「独習C」を持っていませんので、どの様な順序で書かれているか解りません。 ただ C の場合、解らないなりに一通り学習すると、前解らなかった事が、「あ~、これはそういう事だったのか」とすんなり解る事が良くあります。 特にポインタは、ハードウェアに詳しくないのであれば、最初はサッパリ解らないと思います。 ##偉そうに書いていますが、私自身も人からポインタの説明を何度聞いても、良く解りませんでした(^^;。解るようになったのは、自分でそれを使ったプログラムを作ってからでした。 > ほんとうに独習で勉強しています。独習Cより独習に適している教科書があったら、その紹介もお願いします。 技術系に限らず、教科書代わりにする本は、本の質が良くても、自分自身の感覚 (リズムとでもいえば良いのか? 良い表現が見つからないm(__)m) とずれているサッパリ解りません。ですから、大きな書店が近くにあれば、実際に手にとって確認すると良いと思いますが、個人的は、 「明解C言語」など柴田望洋さんの本全般 は解りやすいと思います。
- Tacosan
- ベストアンサー率23% (3656/15482)
「FILE型」は「FILE型」だ, ってあっさり考えた方がいいと思うよ. どうせ中身は見ないわけだし. さらにいうと, 事実上「FILE *」の形でしか使わないんだから, 常にこの形で使うんだって思ってしまっていい. ついでですが, 規格上「FILE型が構造体である」とは限りません.
- SAYKA
- ベストアンサー率34% (944/2776)
fopen は 戻り値が アドレス値、つまりポインタだね。 FILE型というのはstdio.h内で宣言されている構造体で それと同じ物を用意するという話。 で、戻り値がアドレスという事なんだけど これって どういう形の箱なのかが分らないんだよね。 住所だけで 建ってる建物の種類が書いてないって話なので適切に取り出すにはfopenが返すのと同じ形の箱じゃないとならないわけ。 intとかは簡単な形だけどファイルを扱う時はもっと情報量が増えるから、そこで構造体の出番。 とりあえず まず構造体って何よ? ってとこから学んだ方が良いんじゃないかな。。。