C言語ファイルI/O完全ガイド:作成、オープン、管理の実践
ファイル操作の概要
前章ではCプログラミング言語で扱われる標準入出力デバイスを説明しました。この章では、Cプログラマがデータストレージのためにテキストファイルやバイナリファイルを作成、オープン、クローズする方法を扱います。
ファイルは、テキストファイルであれバイナリファイルであれ、バイトのシーケンスを表します。Cプログラミング言語は、ハイレベル関数とローレベル(OSレベル)呼び出しの両方で、ストレージデバイス上のファイルを扱うアクセスを提供します。この章ではファイル管理の重要な呼び出しを説明します。
ファイルのオープン
fopen()関数を使用して新しいファイルを作成したり、既存のファイルを開いたりできます。この呼び出しはFILE型のオブジェクトを初期化し、ストリームを制御するために必要なすべての情報を含みます。この関数のプロトタイプ:
FILE *fopen(const char *filename, const char *mode);
ここで、filenameはファイル名として使用する文字列リテラルで、アクセスモードには以下の値のいずれかを指定できます:
| 番号 | モードと説明 |
|---|---|
| 1 | r 既存のテキストファイルを読み取り用にオープン。 |
| 2 | w テキストファイルを書き込み用にオープン。存在しない場合は新規作成。ファイルの先頭から書き込み開始。 |
| 3 | a テキストファイルを追記モードで書き込み用にオープン。存在しない場合は新規作成。既存ファイルコンテンツに追記。 |
| 4 | r+ テキストファイルを読み書き両用でオープン。 |
| 5 | w+ テキストファイルを読み書き両用でオープン。存在する場合はファイルをゼロ長に切り詰め、存在しない場合は新規作成。 |
| 6 | a+ テキストファイルを読み書き両用でオープン。存在しない場合は作成。読み取りは先頭から、書き込みは追記のみ。 |
バイナリファイルを扱う場合は、上記の代わりに以下のアクセスモードを使用します:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
ファイルのクローズ
ファイルを閉じるにはfclose()関数を使用します。プロトタイプ:
int fclose(FILE *fp);
fclose()関数は成功時にゼロ、ファイルクローズエラー時にEOFを返します。この関数はバッファにまだ残っているデータをファイルにフラッシュし、ファイルを閉じ、ファイルに使用されていたメモリを解放します。EOFはヘッダーファイルstdio.hで定義された定数です。
C標準ライブラリには、ファイルを文字単位で、または固定長文字列の形で読み書きする様々な関数が用意されています。
ファイルへの書き込み
ストリームに個別文字を書き込む最もシンプルな関数:
int fputc(int c, FILE *fp);
fputc()関数は引数cの文字値をfpで参照される出力ストリームに書き込みます。成功時は書き込まれた文字を返し、エラー時はEOFを返します。ヌル終端文字列をストリームに書き込むには以下の関数を使用:
int fputs(const char *s, FILE *fp);
fputs()関数は文字列sをfpで参照される出力ストリームに書き込みます。成功時は非負の値、エラー時はEOFを返します。int fprintf(FILE *fp, const char *format, ...)関数もファイルへの文字列書き込みに使用できます。例:
/tmpディレクトリが利用可能であることを確認してください。存在しない場合は、マシン上にこのディレクトリを作成してから先に進んでください。
#include <stdio.h>
main() {
FILE *fp;
fp = fopen("/tmp/test.txt", "w+");
fprintf(fp, "This is testing for fprintf...\n");
fputs("This is testing for fputs...\n", fp);
fclose(fp);
}
実行すると、/tmpディレクトリに新しいファイルtest.txtが作成され、2つの異なる関数で2行が書き込まれます。次のセクションでこのファイルを読み取ります。
ファイルの読み取り
ファイルから単一文字を読み取る最もシンプルな関数:
int fgetc(FILE *fp);
fgetc()関数はfpで参照される入力ファイルから文字を読み取ります。戻り値は読み取られた文字、エラー時はEOFです。ストリームから文字列を読み取るには以下の関数:
char *fgets(char *buf, int n, FILE *fp);
fgets()関数はfpで参照される入力ストリームから最大n-1文字を読み取り、読み取った文字列をバッファbufにコピーし、文字列を終端するヌル文字を追加します。
この関数が改行文字'\n'またはファイル末尾EOFに遭遇した場合、最大文字数を読み取る前にその時点までの文字(改行文字を含む)のみを返します。int fscanf(FILE *fp, const char *format, ...)関数もファイルから文字列を読み取るために使用できますが、最初のスペース文字に遭遇すると読み取りを停止します。
#include <stdio.h>
main() {
FILE *fp;
char buff[255];
fp = fopen("/tmp/test.txt", "r");
fscanf(fp, "%s", buff);
printf("1 : %s\n", buff);
fgets(buff, 255, (FILE*)fp);
printf("2: %s\n", buff);
fgets(buff, 255, (FILE*)fp);
printf("3: %s\n", buff);
fclose(fp);
}
実行結果:
1 : This 2: is testing for fprintf... 3: This is testing for fputs...
ここで何が起こったか詳しく見てみましょう。まずfscanf()はスペースに遭遇したためThisのみを読み取り、2回目の呼び出しfgets()で行末までの残りを読み取り、最後のfgets()で2行目を完全に読み取りました。
バイナリI/O関数
バイナリ入出力に使用できる2つの関数:
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file); size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
これら両関数は、通常配列や構造体であるメモリブロックの読み書きに使用すべきです。
C言語
- I/Oカードとは? 仕組みと重要性を解説
- Axiomtek IPS960-511-PoE:産業検査向けオールインワン堅牢ビジョン コントローラー
- acceed、統合I/Oモジュール「EDAM-4200シリーズ」を発表-スケーラブルで信頼性の高いデータ通信
- C言語入出力(I/O)マスター:scanf()とprintf()徹底解説
- C言語 ファイル入出力: fopen, fprintf, fread, fseek をマスターする
- C言語の関数マスター:構造、宣言、ベストプラクティス
- C言語ヘッダーファイルの理解:種類、使い方、ベストプラクティス
- C#ファイルI/O:Stream、FileStream、StreamReader/Writerによる読み書き
- MATLABからのデータエクスポート:ファイル形式とテクニック
- PythonファイルI/O:ファイル操作、読み書き、管理のマスター
- PythonファイルI/O:入出力操作をマスターする