問題の歴史:
C言語におけるファイル操作は、初期の言語実装から続く基本的なスキルです。Cの標準ライブラリ(stdio.h)は、入力と出力のストリームに対してポータブルなプログラムを作成するための汎用関数を提供します。
問題:
初心者プログラマーはファイルストリームを扱う際にしばしば間違いを犯します:ファイルを開く結果を確認せず、バッファリングのためのメモリを適切に管理せず、読み取りや書き込みのエラーを処理しません。ファイルを閉じる際のエラーはリソースのリークを引き起こし、バッファを不正に扱うとデータ損失を招きます。
解決策:
ファイルを正しく操作するには、常に以下のことを行う必要があります:
fopenを使ってファイルを開く;fread、fwrite、fscanf、fprintf関数を使用する;fcloseを使ってファイルを閉じる。コード例:
#include <stdio.h> int main() { FILE *fp = fopen("example.txt", "w"); if (!fp) { perror("ファイルを開くことができませんでした"); return 1; } fprintf(fp, "Hello, world! "); fclose(fp); fp = fopen("example.txt", "r"); if (!fp) { perror("読み取り用ファイルのオープン時エラー"); return 1; } char buffer[100]; while (fgets(buffer, sizeof(buffer), fp)) { printf("%s", buffer); } fclose(fp); return 0; }
主な特徴:
fcloseを連続して複数回ファイルを閉じることは可能ですか?
いいえ、ファイルストリームを二重に閉じることは未定義の動作を引き起こします。fcloseの後、ディスクリプタは無効になります。
freadがファイルの終わりに達した場合、何を返しますか?
freadは成功裏に読み取った要素の数を返します。ファイルの終わりに達した場合、返される数は期待される数より少なくなる可能性があります。常にfeofとferrorを確認して診断する必要があります。
同じファイルストリームを同時に書き込みと読み取りに使うことはできますか?
できますが、ファイルが"r+"または"w+"モードで開かれている場合です。ただし、方向(書き込み/読み取り)を変更する前にfflushを呼び出すか、ファイル位置を移動する他の操作(fseek)を行う必要があります。さもなければ、動作は未定義です。
fcloseの後に同じFILE *ポインタを使用する。fflushが呼ばれておらず、ストリームが閉じられていない)。開発者は、fopenからの返り値を確認せずにログファイルにデータを書き込んでいました。ディスクリプタが枯渇するとファイルが開けなくなり、ログメッセージが失われました。
長所:
短所:
別のコードバージョンでは、すべての返り値(fopen、fwrite、fclose)が常に確認されました。エラーが発生した場合は、perrorを使って詳細な診断メッセージが表示され、すべてのリソースを解放してプログラムが正常に終了しました。
長所:
短所: