Cファイルの取り扱い
C ファイルの処理
このチュートリアルでは、C でのファイル処理について学習します。fprintf()、fscanf()、fread()、fwrite()、fseek() などを使用して、C で標準 I/O を処理する方法を学習します。
ファイルは、データの保存に使用されるコンピュータ ストレージ デバイス内のコンテナです。
ファイルが必要な理由
- プログラムが終了すると、データ全体が失われます。ファイルに保存すると、プログラムが終了してもデータが保持されます。
- 大量のデータを入力する必要がある場合は、すべてを入力するのに時間がかかります。
ただし、すべてのデータを含むファイルがある場合は、C でいくつかのコマンドを使用してファイルの内容に簡単にアクセスできます。 - データを変更せずに、あるコンピュータから別のコンピュータに簡単に移動できます。
ファイルの種類
ファイルを扱う場合、知っておくべき 2 種類のファイルがあります:
<オール>1.テキストファイル
テキスト ファイルは通常の .txt ファイル。メモ帳などの単純なテキスト エディタを使用して、テキスト ファイルを簡単に作成できます。
これらのファイルを開くと、ファイル内のすべてのコンテンツがプレーン テキストとして表示されます。内容を簡単に編集または削除できます。
最小限の労力で維持でき、読みやすく、最小限のセキュリティしか提供せず、必要なストレージ スペースが大きくなります。
2.バイナリ ファイル
バイナリ ファイルはほとんどが .bin です
データをプレーン テキストで保存する代わりに、バイナリ形式 (0 と 1) で保存します。
テキスト ファイルよりも大量のデータを保持でき、読み取りが容易ではなく、セキュリティが優れています。
ファイル操作
C では、テキストまたはバイナリのいずれかのファイルに対して 4 つの主要な操作を実行できます。
<オール>ファイルの操作
ファイルを操作するときは、ファイル型のポインターを宣言する必要があります。この宣言は、ファイルとプログラム間の通信に必要です。
FILE *fptr;
ファイルを開く - 作成と編集のために
fopen()
を使用してファイルを開く stdio.h
で定義された関数 ヘッダー ファイル。
標準 I/O でファイルを開くための構文は次のとおりです:
ptr = fopen("fileopen","mode");
たとえば、
fopen("E:\\cprogram\\newprogram.txt","w");
fopen("E:\\cprogram\\oldprogram.bin","rb");
- ファイル
newprogram.txt
を想定してみましょう 場所E:\cprogram
に存在しません .最初の関数はnewprogram.txt
という名前の新しいファイルを作成します モード 'w' に従って書き込み用に開きます .
書き込みモードでは、ファイルの内容を作成および編集 (上書き) できます。 - では、2 番目のバイナリ ファイルが
oldprogram.bin
であるとします。 ロケーションE:\cprogram
に存在します . 2 番目の関数は、バイナリ モード 'rb' で読み取るために既存のファイルを開きます。 .
読み取りモードでは、ファイルの読み取りのみが許可され、ファイルへの書き込みはできません。
モード | モードの意味 | ファイル不在時 |
---|---|---|
r | 読むために開いてください。 | ファイルが存在しない場合、fopen() NULL を返します。 |
rb | バイナリ モードで読み取り用に開きます。 | ファイルが存在しない場合、fopen() NULL を返します。 |
w | 執筆用に開いています。 | ファイルが存在する場合、その内容は上書きされます。 ファイルが存在しない場合は作成されます。 |
wb | バイナリ モードでの書き込み用に開きます。 | ファイルが存在する場合、その内容は上書きされます。 ファイルが存在しない場合は作成されます。 |
a | 追加のために開きます。 データはファイルの末尾に追加されます。 | ファイルが存在しない場合は作成されます。 |
ab | バイナリ モードで追加用に開きます。 データはファイルの末尾に追加されます。 | ファイルが存在しない場合は作成されます。 |
r+ | 読み取りと書き込みの両方が可能です。 | ファイルが存在しない場合、fopen() NULL を返します。 |
rb+ | バイナリ モードで読み取りと書き込みの両方に使用できます。 | ファイルが存在しない場合、fopen() NULL を返します。 |
w+ | 読み取りと書き込みの両方が可能です。 | ファイルが存在する場合、その内容は上書きされます。 ファイルが存在しない場合は作成されます。 |
wb+ | バイナリ モードで読み取りと書き込みの両方に使用できます。 | ファイルが存在する場合、その内容は上書きされます。 ファイルが存在しない場合は作成されます。 |
a+ | 読み取りと追加の両方に対応 | ファイルが存在しない場合は作成されます。 |
ab+ | バイナリモードで読み取りと追加の両方に対応。 | ファイルが存在しない場合は作成されます。 |
ファイルを閉じる
ファイル (テキストとバイナリの両方) は、読み取り/書き込み後に閉じる必要があります。
ファイルのクローズは fclose()
を使用して実行されます 関数。
fclose(fptr);
ここでは、fptr
閉じるファイルに関連付けられたファイル ポインタです。
テキスト ファイルの読み取りと書き込み
テキストファイルの読み書きには、関数 fprintf()
を使用します と fscanf().
それらは printf()
の単なるファイル バージョンです。 と scanf()
.唯一の違いは fprintf()
です と fscanf()
構造体 FILE へのポインターが必要です。
例 1:テキスト ファイルへの書き込み
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
FILE *fptr;
// use appropriate location if you are using MacOS or Linux
fptr = fopen("C:\\program.txt","w");
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
printf("Enter num: ");
scanf("%d",&num);
fprintf(fptr,"%d",num);
fclose(fptr);
return 0;
}
このプログラムは、ユーザーから番号を取得し、ファイル program.txt
に格納します。 .
このプログラムをコンパイルして実行すると、テキスト ファイル program.txt
が表示されます。 パソコンのCドライブに作成。ファイルを開くと、入力した整数が表示されます。
例 2:テキスト ファイルから読み取る
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
FILE *fptr;
if ((fptr = fopen("C:\\program.txt","r")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
fscanf(fptr,"%d", &num);
printf("Value of n=%d", num);
fclose(fptr);
return 0;
}
このプログラムは、program.txt
に存在する整数を読み取ります。
例 1 からファイルを正常に作成した場合 、このプログラムを実行すると、入力した整数が取得されます。
fgetchar()
のような他の関数 、 fputc()
なども同様に使用できます。
バイナリ ファイルの読み取りと書き込み
関数 fread()
と fwrite()
バイナリ ファイルの場合、ディスク上のファイルの読み取りと書き込みにそれぞれ使用されます。
バイナリ ファイルへの書き込み
バイナリ ファイルに書き込むには、fwrite()
を使用する必要があります。 関数。関数は 4 つの引数を取ります:
fwrite(addressData, sizeData, numbersData, pointerToFile);
例 3:fwrite() を使用してバイナリ ファイルに書き込む
#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","wb")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
for(n = 1; n < 5; ++n)
{
num.n1 = n;
num.n2 = 5*n;
num.n3 = 5*n + 1;
fwrite(&num, sizeof(struct threeNum), 1, fptr);
}
fclose(fptr);
return 0;
}
このプログラムでは、新しいファイル program.bin
を作成します Cドライブに。
構造体 threeNum
を宣言します 3 つの数字 - n1、n2、n3 、それをメイン関数で num として定義します。
次に、for ループ内で、fwrite()
を使用して値をファイルに保存します。 .
最初のパラメータは num のアドレスを取ります 2 番目のパラメーターは構造体 threeNum
のサイズを取ります .
num のインスタンスを 1 つだけ挿入しているので、 、3 番目のパラメーターは 1
です .そして、最後のパラメータ *fptr
データを保存しているファイルを指します。
最後に、ファイルを閉じます。
バイナリ ファイルからの読み取り
関数 fread()
fwrite()
と同様に 4 つの引数もとります 上記のように機能します。
fread(addressData, sizeData, numbersData, pointerToFile);
例 4:fread() を使用してバイナリ ファイルから読み取る
#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, fptr);
printf("n1: %d\tn2: %d\tn3: %d\n", num.n1, num.n2, num.n3);
}
fclose(fptr);
return 0;
}
このプログラムでは、同じファイル program.bin
を読み取ります。 レコードを 1 つずつループします。
簡単に言えば、あなたは 1 つの threeNum
を読みます threeNum
の記録 *fptr が指すファイルのサイズ 構造体 num に .
例 3 で挿入したものと同じレコードが得られます .
fseek() を使用してデータを取得する
ファイル内に多数のレコードがあり、特定の位置にあるレコードにアクセスする必要がある場合は、レコードを取得する前にすべてのレコードをループする必要があります。
これにより、多くのメモリと操作時間が浪費されます。 fseek()
を使用すると、必要なデータに簡単にアクセスできます。 .
名前が示すように、fseek()
ファイル内の指定されたレコードにカーソルをシークします。
fseek() の構文
fseek(FILE * stream, long int offset, int whence);
最初のパラメータ ストリームは、ファイルへのポインタです。 2 番目のパラメーターは検索するレコードの位置で、3 番目のパラメーターはオフセットの開始位置を指定します。
いつから | 意味 |
---|---|
SEEK_SET | ファイルの先頭からオフセットを開始します。 |
SEEK_END | ファイルの末尾からオフセットを開始します。 |
SEEK_CUR | ファイル内のカーソルの現在位置からのオフセットを開始します。 |
例 5:fseek()
#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
// Moves the cursor to the end of the file
fseek(fptr, -sizeof(struct threeNum), SEEK_END);
for(n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, fptr);
printf("n1: %d\tn2: %d\tn3: %d\n", num.n1, num.n2, num.n3);
fseek(fptr, -2*sizeof(struct threeNum), SEEK_CUR);
}
fclose(fptr);
return 0;
}
このプログラムは、ファイル program.bin
からレコードの読み取りを開始します 逆の順序 (最後から最初) で印刷します。
C言語