【C语言进阶】--- 文件操作

接触C语言到现在,想必大家对通讯录的实现已经有所耳闻了吧,那么当程序运行结束,重新运行,上次运行的数据就会随程序结束释放,怎么才能保留数据让我们重复使用呢?
想要解决这个问题,你就要接着阅读下去,到篇尾,你或许茅塞顿开,吭哧吭哧的敲你的代码了

1. 文件指针

  • 每个被访问的文件都会开辟一个相应的文件信息区,用来存放文件的相关信息(例如文件的名字、状态、位置)。这些信息被保存在一个结构体中,这个结构体的类型是系统声明的,取名FILE。

  • 当你要读写一个文件时:
    1.打开文件
    2.被打开的文件维护了一个文件信息区
    在这里插入图片描述

  • 每当打开一个文件时,系统会根据文件的情况创建出一个FILE类型的变量,一般是通过FILE的指针来维护这个变量

  • FILE* pf; //文件指针变量

  • pf是一个指向FILE类型数据的指针变量,可以让pt指向某个文件的文件信息区,通过这个文件信息区就能访问该文件

2. 文件的打开与关闭

2.1 文件的打开

FILE* fopen(const char* filename, const char* mode);

  • filename是要打开文件的路径,mode是操作指令,比如说你要是为了读文件啊还是写文件
  • 返回的是文件信息区的地址,如果打开失败会返回NULL指针,因此执行该函数后需要即使判断是否打开失败,避免造成野指针

    该图取自C技能树

2.2 文件的关闭

int fclose(FILE* stream);

  • stream是指向文件的指针
  • 若关闭失败返回EOF,成功返回0
FILE* pf = fopen("test.txt","w");//打开并读取文件
if(pf == NULL)//判断是否打开成功
{
	perror("fopen");//提示打开失败的原因
	return 1;
}
fclose(pf);//关闭文件

3. 文件的顺序读写(函数)

首先要链接程序什么情况下是读,什么情况下是写
在这里插入图片描述

3.1 fputc函数(字符输出)

int fputc ( int character, FILE * stream );

  • 功能:向文件中写字符,指针向前进1,character是要写入的字符,stream是指向文件信息区的指针
  • 写入成功,返回该字符的ASCII码值
  • 写入失败,返回EOF
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputc('a', pf);
	/*for (int i = 0; i < 10; i++)
	{
		fputc('a' + i, stdout);//stdout标准输出流,将内容展现在屏幕
	}*/

	fclose(pf);

	return 0;
}

3.2 fgetc函数(字符输入)

int fgetc ( FILE * stream );

  • 功能:读取文件中的字符(stream指向文件信息区),指针+1
  • 返回读取到字符的ASSCII码值
  • 读取失败返回EOF
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = fgetc(pf);//将从文件中读取到的字符返回给ch,此时pf已经指向下一个字符的位置
	printf("%c\n", ch);
	ch = fegetc(pf);
	/*int arr[11] = { 0 };//利用stdin标准输入流读取键盘上输入的字符
	for (int i = 0; i < 11; i++)
	{
		arr[i] = fgetc(stdin);
		printf("%c", arr[i]);
	}*/

	fclose(pf);

	return 0;
}

3.3 fputs函数(字符串输出)

int fputs ( const char * str, FILE * stream );

  • 功能:写,将字符串写入到文件中,str是要写入字符串的首地址,stream是指向文件信息区的指针
  • 成功返回非负值
  • 失败返回EOF
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[] = "asdasd";
	fputs(arr, pf);
	

	fclose(pf);

	return 0;
}

3.4 fgets(字符串输入)

char * fgets ( char * str, int num, FILE * stream );

  • 功能:向文件中读取num-1个字符拷贝到str中
  • 若读取到\n换行符则停止,并且会将拷贝到的字符末尾追加一个\0
  • 读取成功返回字符串
  • 读取失败返回NULL
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[10] = { 0 };
	fgets(arr, 10, pf);
	printf("%s\n", arr);
	fclose(pf);

	return 0;
}

3.5 fwrite函数(二进制写文件)

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

  • 功能:从ptr指向的空间拷贝count个大小为size字节的内容给文件
  • 返回实际写入的个数
int main()
{
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int ret = fwrite(arr, sizeof(int), 10, pf);
	printf("%d\n", ret);
	
	fclose(pf);

	return 0;
}

3.6 fread函数(二进制读文件)

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

  • 功能:从文件中读取count个大小为size个字节的数据拷贝给ptr指向的空间
  • 返回读取到元素的个数
int main()
{
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[10] = { 0 };
	fread(arr, 4, 10, pf);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}

	fclose(pf);

	return 0;
}

4. 文件随机读写

4.1 fseek函数

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

  • offset是偏移的距离,origin是从哪里开始偏移
  • origin有三个选择:
    • SEEK_SET(文件起始位置)
    • SEEK_CUR(文件当前位置)
    • SEEK_END(文件末尾)
  • 功能:从origin
  • 给定的位置偏移offset个位置,读取字符,返回字符的ASCII码值
  • 偏移:offset可正可负,是文件指针移动

4.2 ftell函数

long int ftell(FILE* stream);
功能:返回文件指针距离起始位置的偏移量

4.3 rewind函数

void rewind(FILE* stream);
功能:让文件指针的位置回到起始位置

5. 文件读取结束判断

  1. 不能用feof函数的返回值直接判断文件是否结束
    feof的作用是在文件读取结束后,判断读取结束的原因是不是遇到文件尾结束
  2. 如何判断读取是否结束,判断返回值是不是EOF(fgetc),或者NULL(fgets)
    例如:
    • fegetc判断是否为EOF
    • fgets判断返回值是否为NULL
  3. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数
    fread判断返回值是否小于实际要读的个数

6. 文件缓冲区

当缓冲区的数据满了才会一起传送数据
或者刷新缓冲区即可,fclose就可以刷新缓冲区,这样可以保证关闭文件前数据不会丢失
在这里插入图片描述

  • 28
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值