C言語によるファイルの読み書き

勝ち負けではなく、正しいか間違っているかを問うだけだ

記事ディレクトリ

1. 文書の概要  

2. ファイルの読み取りと書き込みとは何ですか

第三に、ファイル処理機能

1. ファイルの開閉

2. ファイルのシーケンシャルな読み取りと書き込み

ファイルのシーケンシャル読み取りおよび書き込み関連関数

scanf ファミリと printf ファミリの比較と区別

3. ファイルのランダムな読み取りと書き込み      

ファイルのランダムな読み取りおよび書き込み機能

4. ファイルバッファ

5. ファイル読み込み終了の判定

ファイルが読み込まれたかどうかを判断する 2 つの基準

悪用されたフェフ


  みなさん、こんにちは。私は Ji Ning です。資格のあるプログラマーとして、プログラムでのファイルの作成と使用のメカニズムを理解する必要があります。この記事ではC言語のファイルに関する内容を紹介します。

1. 文書の概要  

  ファイルはコンピュータ システムの非常に重要な部分であり、文書、写真、表、手紙、ビデオなどのさまざまな情報を保存するためによく使用されます。データの永続性の変更を実現できます。次に、プログラムでファイルの読み取りと書き込み、またはファイルの作成を学ぶことが非常に重要です。 

  プログラミングでは、通常、プログラム ファイルとデータ ファイルという 2 種類のファイルについて話します。プログラム ファイルとは、ソース ファイル (拡張子 .c が付く)、オブジェクト ファイル (拡張子 .obj が付く)、実行可能ファイル (Windows システムでは拡張子 .exe が付く) など、プログラム自体のファイルを指します。 ; データ ファイルとは、データの読み取りおよび書き込み時に実行されるプログラムを指します。この記事では、データ ファイルについて説明します。

  ファイルには、ユーザーの識別と参照のために一意のファイル識別子が必要です。ファイル名は、ファイル パス + ファイル名トランク + ファイル サフィックスの 3 つの部分で構成されます例: c:\code\test.txt便宜上、ファイル ID はファイル名と呼ばれることがよくあります。

  C では、ファイルは一連のバイトとして見なされ、それぞれを個別に読み取ることができます。C には、テキスト モードとバイナリ モードの2 つのファイル モードが用意されています

  テキスト モードとバイナリ モードを区別するには、すべてのファイルの内容がバイナリ形式 (0 または 1) で保存されるということを最初に明確にする必要があります。ファイルがもともとテキストを表すためにバイナリ エンコードされた文字を使用していた場合、そのファイルはテキスト コンテンツを含むテキスト ファイルです。ファイル内のバイナリ値が機械語、数値データ、または何らかの音楽エンコードを表している場合、そのファイルはバイナリ ファイル 。バイナリ コンテンツが含まれます。

2. ファイルの読み取りと書き込みとは何ですか

  ファイルの読み込みとは、ファイルを読み込み、ハードディスク内のファイルの内容を読み出して利用することです。ファイルの書き込みとは、次回読み取りできるように、ハードディスク上の特定のファイルにデータを書き込むことです。ファイルの読み取りは入力に相当し、ファイルの書き込みは出力に相当します。プログラムの場合、ファイルからのデータの読み取りはキーボードからのデータの入力に相当し、ファイルへのデータの書き込みは画面上にデータを出力することに相当します。

第三に、ファイル処理機能

1. ファイルの開閉

  ファイルを開くには、C 言語の fopen() 関数を使用します。この関数は <stdio,h> で宣言されます。最初のパラメータは、開かれたファイルのアドレスを指すポインタで、通常はファイル ポインタとも呼ばれます。2 番目のパラメータは、開くファイルのモードを指定する文字列です。次の表に、C で一般的に使用されるモードをいくつか示します。

パターン文字列 意味
「r」 読み取り用にファイルを開く
「わ」 ファイルを書き込みモードで開き、このファイルの既存のコンテンツをすべて削除します。テキストが存在しない場合は、ファイルを作成します。
「あ」 ファイルを書き込みモードで開き、ファイルの末尾にコンテンツを追加するか、ファイルが存在しない場合は作成します。
「r+」 ファイルを更新モードで開きます(ファイルの読み取りと書き込みが可能)
「w+」 ファイルを更新モードで開きます (つまり、読み取りと書き込みが可能です)。ファイルが存在する場合は、ファイルの内容を読み取った後、ファイルのすべての内容が削除されます (長さは 0 に切り捨てられます)。存在しない場合は、新しいファイルが作成されます
「a+」 ファイルを更新モードで開き (つまり、読み取りと書き込みが可能)、既存のファイルが存在する場合はその末尾に追加し、存在しない場合は新しいファイルを作成します。ファイル全体を読み取ることはできますが、ファイルから追加することはできません。終わり

「rb」、「wb」、「ab」、「rb」、「rb+」

「r+b」、「w+b」、「wb+」、「ab+」、「a+b」

文字列に b を追加した後の関数は前の関数と似ていますが、ファイルはバイナリ モードではなくテキスト モードで開かれます。

プログラムがファイルを正常に開くと、 fopen() はファイル ポインター ( file pointer )  を返します。ファイル ポインターの型は FILE へのポインターであり、FILE は <stdio.h> で定義された型です。ただし、pf は実際のファイルを指すのではなく、情報ファイルを含むデータ オブジェクトを指します。たとえば、ファイルの読み取りと書き込みを行う次のコード

    FILE* pf = fopen("mhj.txt", "r");//以文本模式读文件
	FILE* pf = fopen("mhj.txt", "w");//以文本模式写文件
	FILE* pf = fopen("mhj.txt", "rb");//以二进制模式读文件
	FILE* pf = fopen("mhj.txt", "wb");//以二进制模式写文件

  fclose(pf) 関数は、pf で指定されたファイルを閉じ、必要に応じてバッファをフラッシュできます。クローズが成功した場合、fclos() 関数は 0 を返し、それ以外の場合は EOF を返します。閉じた後、pf ポインターがワイルド ポインターになるのを防ぐために、pf ポインターを適時にクリアする必要があります。

    fclose(pf);
	pf = NULL;

2. ファイルのシーケンシャルな読み取りと書き込み

ファイルのシーケンシャル読み取りおよび書き込み関連関数

関数 関数名 に適用する
文字入力 fgetc すべての入力ストリーム
文字出力 fputc すべての出力ストリーム
テキスト行入力 fgets すべての入力ストリーム
テキスト行出力 fputs すべての出力ストリーム
フォーマットされた入力 fscanf すべての入力ストリーム
フォーマットされた出力 fprintf すべての出力ストリーム
バイナリ入力 恐れる 書類
バイナリ出力 fwrite 書類

  fgetc 関数と fputc 関数は getchar 関数と putcgar 関数に似ていますが、後者はキーボードからの読み取り (入力) と画面への書き込み (出力) を行うのに対し、前者はすべてのストリームから入出力できる点が異なります。

  たとえば、次のステートメントは、標準入力ストリームから文字を取得することを意味します。

ch=getchar();

同じ機能、fgetc も次のことを実行できます。

ch=fgetc(stdin);

もちろん、fgetc の主な機能はファイルから文字を読み取ることですが、次のステートメントは pf で指定されたファイルから文字を取得することを意味します。

ch=fgetc(pf);

  これらのファイル操作関数を使用する場合は、標準の入出力ストリーム関数の使用法を模倣することができ、パラメータと書き込むファイルポインタの名前に注意するだけで済みます。

ファイル入出力関数

関数の戻り値の型とパラメータ
fgetc int fgetc ( ファイル * ストリーム );
fputc int fputc ( int 文字, FILE * ストリーム );
fgets char * fgets ( char * str, int num, FILE * stream );
fputs int fputs ( const char * str, FILE * stream );
fscanf int fscanf ( FILE * ストリーム、const char * フォーマット、... );
fprintf int fprintf ( FILE * ストリーム, const char * フォーマット, ... );
恐れる size_t fread ( void * ptr, size_t サイズ, size_t カウント, FILE * stream );
fwrite size_t fwrite ( const void * ptr, size_t サイズ, size_t カウント, FILE * stream );

scanf ファミリと printf ファミリの比較と区別

  scanf 関数と printf 関数は、標準の入出力ストリーム、つまりキーボードからの入力にのみ適用できますが、fprint 関数と fscanf 関数は、いくつかのパラメータを追加して、すべての入出力ストリームに使用されます。int sprintf ( char * str, const char * format, ... );

  sscanf関数、sprintf関数はデータを文字列に変換する機能を持っています。まず、これらの関数のパラメータと戻り値を観察します。

sscanf        int sscanf ( const char * s, const char * format, ...);
スプリントフ        int sprintf ( char * str, const char * format, ... );

  format はフォーマットを意味します。フォーマットの 1 つはパラメータに対応します。sscanf sprintf は標準入力ストリームと同じですが、パラメータ リストに追加のポインタがあります。

  char buffer [50];
  int n, a=5, b=3;
  n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
  printf ("[%s] is a string %d chars long\n",buffer,n);

上記のコードの意味は、二重引用符内のすべてのデータを文字列に変換し、バッファーに入れることです。

3. ファイルのランダムな読み取りと書き込み      

ファイルのランダムな読み取りおよび書き込み機能

fseek int fseek ( FILE * stream, long int offset, int origin );
ftell long int ftell ( FILE * stream );
rewind void rewind ( FILE * stream );

  fseek函数:可以将文件看做数组,在fopen打开的文件中直接定位到任意字节处,根据文件指针的位置和偏移量来定位文件指针。

int main()
{
	FILE* pFile;
	pFile = fopen("example.txt", "wb");
	fputs("This is an apple.", pFile);
	fseek(pFile, 9, SEEK_SET);
	fputs(" sam", pFile);
	fclose(pFile);
	return 0;
}

  ftell函数:返回文件指针相对于起始位置的偏移量

​
#include <stdio.h>
int main()
{
	FILE* pFile;
	long size;
	pFile = fopen("myfile.txt", "rb");
	if (pFile == NULL) perror("Error opening file");
	else
	{
		fseek(pFile, 0, SEEK_END);  
		size = ftell(pFile);
		fclose(pFile);
		printf("Size of myfile.txt: %ld bytes.\n", size);
	}
	return 0;
}

​

rewind函数:让文件指针的位置回到文件的起始位置

#include <stdio.h>
int main()
{
	int n;
	FILE* pFile;
	char buffer[27];
	pFile = fopen("myfile.txt", "w+");
	for (n = 'A'; n <= 'Z'; n++)
		fputc(n, pFile);
	rewind(pFile);
	fread(buffer, 1, 26, pFile);
	fclose(pFile);
	buffer[26] = '\0';
	puts(buffer);
	return 0;
}

  上述代码的意思是先将字符A~Z写入文件 myfile.txt ,再用rewind函数使文件指针回到起始位置,再以二进制的形式读取它们。

四、文件缓冲区

  缓冲区,即临时储存数据的地方,可以提高效率节约时间。且缓冲区这个概念不止在文件里有。在平时输入输出的时候,也会有缓冲区,当用户打错字符的时候,可以直接通过键盘修正,最后按下Enter键,传输的才是正确的输入。下面以文件的缓冲区为例介绍缓冲区是如何提高效率的。

  如果内存从硬盘中拿数据的时候,硬板每输入一个数据,内存就拿一次,每输入一个数据,内存就拿一次......那么内存的内存读取的负担就会非常大,有些数据是源源不断的从硬盘传递过来的,所以就有了缓冲区这个概念。

  缓冲区是系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。计算机从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上;如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等),缓冲区的大小是由C原因的编译器自身决定的。

五、文件的读取结束的判定

判断文件是否读取结束的两个标准

  1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:fgetc 判断是否为 EOF ,fgets 判断返回值是否为 NULL。

  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:fread判断返回值是否小于实际要读的个数。

被错误使用的feof

  feof函数的作用是:当文件读取结束的时候,判断是读取结束的原因是否是 遇到文件尾结束。要牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束

在用上述两个方法判断是否结束后,在用feof函数判断读取结束的原因

//判断是什么原因结束的
if (ferror(fp))
	puts("I/O error when reading");
else if (feof(fp))
	puts("End of file reached successfully");

非常感谢各位对纪宁的支持,你们的支持就是我不断更新的动力

おすすめ

転載: blog.csdn.net/zyb___/article/details/131863870
おすすめ