Cprogramming-c-file-io
C-ファイルI/O
最後の章では、Cプログラミング言語で処理される標準入出力デバイスについて説明しました。 この章では、Cプログラマがデータストレージ用のテキストファイルまたはバイナリファイルを作成、開く、閉じる方法について説明します。
ファイルは、テキストファイルまたはバイナリファイルに関係なく、バイトシーケンスを表します。 Cプログラミング言語は、ストレージデバイス上のファイルを処理するための低レベル(OSレベル)呼び出しだけでなく、高レベル関数へのアクセスを提供します。 この章では、ファイル管理の重要な呼び出しについて説明します。
ファイルを開く
- fopen()関数を使用して、新しいファイルを作成したり、既存のファイルを開くことができます。 この呼び出しは、ストリームを制御するために必要なすべての情報を含む *FILE 型のオブジェクトを初期化します。 この関数呼び出しのプロトタイプは次のとおりです-
FILE *fopen( const char *filename, const char* mode );
ここで、*ファイル名*は文字列リテラルであり、ファイルに名前を付けるために使用します。アクセス*モード*は次のいずれかの値を持つことができます-
Sr.No. | Mode & Description |
---|---|
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(-)関数は成功すると0を返し、ファイルを閉じるときにエラーが発生した場合は *EOF を返します。 この関数は、バッファ内でまだ保留中のデータをファイルに実際にフラッシュし、ファイルを閉じて、ファイルに使用されているメモリを解放します。 EOFは、ヘッダーファイル stdio.h で定義されている定数です。
ファイルを1文字ずつ、または固定長文字列の形式で読み書きするために、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 にコピーし、文字列を終了するために null 文字を追加します。
この関数は、最大文字数を読み取る前に改行文字「\ 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);
これらの関数は両方とも、メモリのブロック(通常は配列または構造)の読み取りまたは書き込みに使用する必要があります。