C语言文件操作


C语言中,通过FILE*的文件指针来维护流的各种操作

文件的打开和关闭

文件指针

缓冲⽂件系统中,关键的概念是“⽂件类型指针”,简称“⽂件指针”。
每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名
字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系
统声明的,取名FILE
例如创建一个文件指针

FILE* pf;

定义pf是⼀个指向FILE类型数据的指针变量。可以使pf指向某个⽂件的⽂件信息区(是⼀个结构体变量)。通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件

文件的打开和关闭

⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件
在编写程序的时候,在打开⽂件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了
指针和⽂件的关系。
ANSI C 规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件
在这里插入图片描述

//打开文件
FILE* fopen ( const char* filename, const char* mode);
//关闭文件
int fclose ( FILE* stream);

filename表示文件名
mode表示文件的打开方式,下面都是文件的打开方式

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if ( !pf )
	{
		perror("fopen");
		return 1;
	}
	fclose(pf);
	pf = NULL;
	
	return 0;
}

文件的顺序读写

在这里插入图片描述

fgetc与fputc的使用

//写文件--fputc
//int fputc ( int character, FILE * stream );
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	/*fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);*/

	char ch = 0;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		fputc(ch, pf);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
//读文件--fgetc
//int fgetc ( FILE * stream );
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	//如果成功读取字符的话,返回的是字符的ASCII码值-char
	//如果读取遇到文件末尾,或者读取失败的时候,返回EOF(-1)
	char c = 0;
	while ((c = fgetc(pf)) != EOF)
	{
		printf("%c", c);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

fgets与fputs的使用

//写文件--fputs
//int fputs ( const char * str, FILE * stream );
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	fputs("hello world\n", pf);
	fputs("hello bit\n", pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
//读文件--fgets
//char * fgets ( char * str, int num, FILE * stream );
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	//char * fgets ( char * str, int num, FILE * stream );
	//只读num - 1个数据、最后一个放\0
	//读取成功返回str
	//读取错误返回NULL
	char ch[20] = { 0 };
	while (fgets(ch, 20, pf) != NULL)
	{
		printf("%s", ch);
	}
	
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

fscanf与fprintf的使用

//写文件--fprintf
//int fprintf ( FILE * stream, const char * format, ... );
struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "哈哈",18,65.5f};
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}

	//写文件  - 是以文本的形式写进去的
	//int fprintf ( FILE * stream, const char * format, ... );
	fprintf(pf, "%s %d %f", s.name, s.age, s.score);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
struct S
{
	char name[20];
	int age;
	float score;
};

//读文件--fscanf
//int fscanf ( FILE * stream, const char * format, ... );
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}


	struct S s = { 0 };

	//读文件
	//从文件test.txt中读取数据放到s中
	//int fscanf ( FILE * stream, const char * format, ... );
	fscanf(pf, "%s %d %f", s.name, &s.age, &s.score);
	//打印在屏幕上
	printf("%s %d %f\n", s.name, s.age, s.score);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

fread与fwrite的使用

//写文件--fwrite 
//size_t fwrite(const void* ptr, size_t size, size_t count, FILE * stream);
int main()
{
	int arr[] = { 1,2,3,4,5 };
	//打开文件
	FILE* pf = fopen("test.txt", "wb");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	int sz = sizeof(arr) / sizeof(arr[0]);
	fwrite(arr, sizeof(arr[0]), sz, pf);//以二进制的形式写进去

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
//写文件--fread 
//size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
int main()
{
	int arr[5] = { 0 };
	//打开文件
	FILE* pf = fopen("test.txt", "rb");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	//size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
	//读二进制文本
	int i = 0;
	while (fread(&arr[i], sizeof(arr[0]), 1, pf))
	{
		printf("%d ", arr[i++]);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

文件的随机读写

1.fseek :根据⽂件指针的位置和偏移量来定位⽂件指针。

int fseek (FILE* stream, long int offset, int origin);
offset:距离origin偏移量
origin:

  1. SEEK_SET:光标起始位置.
  2. SEEK_CUR:光标当前位置.
  3. SEEK_END:光标末端位置.

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

long int ftell ( FILE* stream);

3.rewind:让文件指针的位置回到文件的起始位置

void rewind ( FILE* stream);

文件的随机读写
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (!pf)
	{
		perror("fopen");
		return 1;
	}
	//读文件

	//fseek
	char ch = fgetc(pf);
	printf("%c\n", ch);

	fseek(pf, 4, SEEK_CUR);//文件当前位置
	ch = fgetc(pf);
	printf("%c\n", ch);

	fseek(pf, 5, SEEK_SET);//文件起始位置
	ch = fgetc(pf);
	printf("%c\n", ch);

	fseek(pf, -4, SEEK_END);//文件结束位置
	ch = fgetc(pf);
	printf("%c\n", ch);

	//ftell--返回文件指针相对起始位置的偏移量
	fseek(pf, 0, SEEK_END);
	printf("%d\n", ftell(pf));

	//rewind--让文件指针回到文件的其实位置
	rewind(pf);
	ch = fgetc(pf);
	printf("%c\n", ch);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

文件读取结束的判断

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

  1. ⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
    例如:
    • fgetc 判断是否为 EOF .
    • fgets 判断返回值是否为 NULL .
  2. ⼆进制⽂件的读取结束判断,判断返回值是否⼩于实际要读的个数。
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (!pf)
		return 1;
	char ch = 0;
	while ((ch = fgetc(pf) != EOF))
	{
		printf("%c ", ch);
	}
	//判断是什么原因结束的
	if (feof(pf))
		printf("遇到文件末尾,读取正常结束\n");
	else if (ferror(pf))
		perror("fgetc");
	return 0;
}

文件拷贝

拷贝文件:test1.txt--->test2.txt
int main()
{
	FILE* pfin = fopen("test1.txt", "r");
	if (!pfin) {
		perror("fopen:test1.txt");
		return 1;
	}
		
	FILE* pfout = fopen("test2.txt", "w");
	if (!pfout) {
		fclose(pfin);
		perror("fopen:test2.txt");
		return 1;
	}

	//读文件和写文件
	int ch = 0;
	while ((ch = fgetc(pfin)) != EOF)
	{
		fputc(ch, pfout);
	}
	fclose(pfin); 
	pfin = NULL;
	fclose(pfout);
	pfout = NULL;
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值