C言語ファイルの読み取りと書き込み-バイトごと、行ごと+ファイルの読み取りと書き込みの場合、最後の行は2回読み取られます。

テキストフロー

  テキストストリーム、つまり、テキストモードでファイルを読み取るとよく言われます。テキストストリームの一部の特性は、システムによって異なる場合があります。それらの1つは、テキスト行の最大長です。規格では、少なくとも254文字が許可されると規定されています。異なる可能性のあるもう1つの機能は、テキスト行の終了方法です。たとえば、Windowsシステムでは、テキストファイルはキャリッジリターンとラインフィードで終了することに同意しています。ただし、Linuxでは、改行の終わりのみが使用されます。

   標準Cは、テキストを0文字以上として配置し、その後に終了を示す改行文字(\ n)を続けます。テキスト行の外部表現がこの定義と異なるシステムの場合、ライブラリ関数は外部および内部フォームフォーム間の変換。たとえば、Windowsシステムでは、出力時に、テキストの改行文字がキャリッジリターン/ラインフィードのペアとして書き込まれます。入力すると、テキスト内の改行は破棄されます。外部フォームを考慮せずにテキストを操作するこの機能により、ポータブルプログラムの作成が簡単になります。

バイナリストリーム

  バイナリストリームのバイトは、プログラムが書き込まれる形式に従って完全にファイルに書き込まれ、ファイルまたはデバイスから読み取られる形式に従って、変更なしでプログラムに完全に読み込まれます。このタイプのストリームは非テキストデータに適していますが、I / O関数でテキストファイルの行末文字を変更したくない場合は、それらをテキストファイルに使用することもできます。

   C言語は、これら2種類のファイルを区別せず、文字ストリームとして扱われ、バイト単位で処理されます。

   プログラムでよく見られるテキストモードとバイナリモードで開いているファイルは、改行の処理にのみ反映されます。

   たとえば、Windowsではファイルの改行文字は\ r \ nですが、Linuxでは\ n

   ファイルをテキストモードで開くと、読み取り/書き込みWindowsファイルの改行文字\ r \ nが\ nに置き換えられ、メモリに読み込まれます。ファイルがWindowsで書き込まれると、\ nは\ rに置き換えられます。 \ nファイルを再度書き込みます。ファイルをバイナリモードで開いた場合、\ r \ nと\ nの間の変換は実行されません。Linuxでは改行文字が\ nであるため、テキストファイルとバイナリファイルに違いはありません。

ファイルの読み取りおよび書き込み機能

1.文字に従ってファイルを読み書きします:fgetc()、fputc()

2.ファイルを1行ずつ読み取りおよび書き込みます:fputs()、fgets()

3.ブロック内のファイルの読み取りと書き込み:fread()、fwrite()

4.次の形式に従ってファイルを読み書きします:fprintf()、fscanf()

5.ランダムな位置に従ってファイルを読み書きします:fseek()、ftell()、rewind()

文字ごとのファイルの読み取りと書き込み

#include<stdio.h>
#include<string.h>
#pragma pack(show)



void test01()
{
	int i;
	char ch;
	char buff[] = "hello world";
	FILE* f_read;
	//写文件
	FILE* f_write = fopen("./test1.txt","w");


	if(f_write == NULL)
		return;

	
	for(i = 0;i < strlen(buff);i++)
	{
		fputc(buff[i],f_write);
	}
	fclose(f_write);

	//读文件
	//FILE* f_read = fopen("./test1.txt","r");
	f_read = fopen("./test1.txt","r");
	if(f_read == NULL)
		return;
	while((ch = fgetc(f_read)) != EOF)
	{
		printf("%c",ch);
	}
	fclose(f_read);
}


int main()
{
	test01();

	return 0;
}

演算結果:

こんにちは世界

同時に、test1.txtファイルは.cファイルと同じレベルのディレクトリに表示されます

行ごとのファイルの読み取りと書き込み

#include<stdio.h>
#include<string.h>
#pragma pack(show)



void test01()
{
	int i;
	char ch;
	char temp[1024] = {0};
	
	FILE* f_read;
	//写文件
	FILE* f_write = fopen("./test2.txt","w+");
	char* buff[]=
	{
		"锄禾日当午\n",
		"汗滴禾下土\n",
		"谁知盘中餐\n",
		"粒粒皆辛苦\n"
	};

	if(f_write == NULL)
		return;

	
	for(i = 0;i < 4;i++)
	{
		fputs(buff[i],f_write);
	}
	fclose(f_write);

	//读文件
	//FILE* f_read = fopen("./test1.txt","r");
	f_read = fopen("./test2.txt","r");
	if(f_read == NULL)
		return;

	
	while(!feof(f_read))
	{
	
		fgets(temp,1024,f_read);
		printf("%s",temp);
	}
	fclose(f_read);
}


int main()
{
	test01();

	return 0;
}

演算結果:

鍬入れ当日、土に
汗が滴り落ちる。お皿の
中華料理

大変だと誰が知っているの
か、キーを押して続行してください...

最後の行が2回読み取られたことがわかりましたが、どうなりましたか?

 

stdio.hで次の定義確認できます。

1

2

3

4

5

6

7

8

9

#define EOF (-1)

#define _IOEOF 0x0010

#define feof(_stream) ((_stream)->_flag & _IOEOF)

int c;

while(!feof(fp))

{

    c = fgetc(fp);

    printf("%X\n", c);

}

その理由は、最後の文字を読み取った後もfp-> flagが_IOEOFに設定されていないため、feof()がファイルの終わりを検出しないためです。読み取り操作を実行するためにfgetc()が再度呼び出されるまで、feof()はファイルの終わりを検出できません。

引用元:https//baike.baidu.com/item/feof/10942186?fr = aladdin

したがって、改善点は次のとおりです。

fgets(temp、1024、f_read);
    while(!feof(f_read))
    {         printf( "%s"、temp);         fgets(temp、1024、f_read);     }


        

 

おすすめ

転載: blog.csdn.net/weixin_42596333/article/details/104521765