《C指针编程之道》笔记——6.3文件操作函数汇总


前言

据我所知,大部分C语言的初学者在使用C语言的场景都是在刷网站上的算法题,而网站上的算法题基本上是不会使用文件相关的操作的,所以初学者往往会忽略掉对于C语言对于文件的操作指令。本节将对C语言的文件操作指令做一个汇总。


一、文件加工厂

1.fopen()

函数原型:FILE *fopen(char const *name,char const *mode);//参数分别为:文件名和打开文件的方式

打开文件的方式如下:
在这里插入图片描述
fopen()的返回值是一个文件类型指针FILE *。如果文件打开失败,则返回NULL。

2.fclose()

函数原型:int fclose(FILE *fp);

参数为文件指针。有一个整数返回值,可以用一个整型变量接收,也可以不接收,当文件关闭成功时返回值为0,否则返回EOF。

3.fgetc()

函数原型:int fgetc(FILE *fp);

从指定文件中读取一个字符,返回值为从文件中读取出的字符的ASCII码值,若读到文件结束符则函数返回文件结束标志EOF。

4.fputc()

函数原型:int fputc(int c,FILE *fp);

将字符c传入到文件fp当中,虽然函数原型中形参为int类型,但是可以传入字符char类型的变量。返回值为字符c的ASCII码值,写入失败返回EOF。

5.fgets()

函数原型:char *fgets(char *s,int n,FILE *fp);

从指定的文件中读取字符串。函数有3个参数,第一个参数s为暂存读出字符串的缓冲区,第二个参数n为一次读取的最大字符个数,fp为文件指针。
fgets()从fp中读取字符,当读到换行回车符、文件末尾、满n-1个字符时在字符串末尾加上一个’\0’,把它们存放到字符数组s中,并返回结果为s的首地址。若在任何字符读取前就达到了文件末尾,fgets()返回NULL指针用于检查是否读到文件尾。

6.fputs()

函数原型:int *fputs(const char *s,FILE *fp);

向文件中写入字符串s,字符串应以’\0’结尾。写入成功返回0,写入失败返回EOF,返回值可接收也可不接收。

7.fread()

函数原型:unsigned fread(void *s,unsigned size,unsigned count,FILE *fp)

这个函数一般用于对二进制文件进行操作,此外用于二进制文件操作的函数还有fwrite()、fseek()。

fread()的功能是从文件中读取出一组数据。函数有4个参数,第一个参数为从文件读取出的数据应存入的地址,第二个参数size为读出的每个数据块的字节数大小,第三个参数count为允许读出多少个大小为size的数据块的个数,第四个参数为文件指针。返回值为实际读出的数据块个数。

8.fwrite()

函数原型:unsigned fwrite(const void *s,unsigned size,unsigned count,FILE *fp);

向文件中写入一组数据。它的参数形式与fread()相同,所以不再赘述,参考fread()的参数格式即可。返回值为实际写入的数据块个数。

9.fprintf()

函数原型:int fprintf(FILE *fp,const char *format,…);

fprintf()的使用和printf()十分相似。不同点在于printf()的输出对象是终端,而fprintf()的输出对象是文件,并且fprintf()要传入的参数有文件指针,其它格式与printf()相同。

10.fscanf()

函数原型:int fscanf(FILE *fp,const char *format,…);

fscanf()与scanf()相似,在用法上可以参考fprintf()。

但由于fprintf()和fscanf()对文件进行读写时,输入要将ASCII码转换成二进制数,输出要将二进制数转换成字符,所以时间开销比较大,所以一般不建议使用fprintf()和fscanf()。

11.fseek()

函数原型:int fseek(FILE *fp,long offset,int from);

用于对文件指针进行重定位。
之前的文件操作函数都是从头开始对文件进行顺序读写的,这是由于文件指针开始时都是指向文件头,然后不断移动到下一个字符。而fseek()可以将文件指针定位到用户指定的位置开始对文件进行读写操作,从而实现对文件的随机读写。
fseek()有三个参数,第一个参数为要读写的文件,第二个参数offset为位移量,它是以起始点from为基点,向前移动的字节数,第三个参数from为定位起始点。
from的取值有如下几种:
在这里插入图片描述
一定要注意,fseek()只能用于二进制文件,对文本文件的定位会产生混乱!!

12.rewind()

函数原型:void rewind(FILE *fp);

使文件指针返回到文件开头。

13.ftell()

函数原型:long ftell(FILE *fp);

得到文件指针当前位置,用相对于文件头的位移量来表示。出错时返回-1。
这个函数一般搭配fseek()来使用,将ftell()的返回值作为fseek()的offset参数,此时fseek()的from应为SEEK_SET。

14.feof()

函数原型:int feof(FILE *fp);

判断当前文件指针是否读到文件尾,若是则返回值为真,否则返回值为0。

二、学以致用

接下来通过一些练习来巩固一下以上提到的文件操作函数。

例一

题目:从键盘输入3个关于图书的数据,存入文件,再从文件中取出输出显示到屏幕上。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 3

/*图书数据结构体,并定义全局数组BOOK_ARRAY*/
struct book_info {
	char name[20];//书本名字
	char author[20];//书本作者
	char publisher[20];//书本出版商
}BOOK_ARRAY[MAXSIZE];

int WriteFile(const char *WFile);
int ReadFile(const char *RFile);

int main() {
	const char* File = "MyBookFile.txt";
	for (int i = 0; i < MAXSIZE; i++) {
		printf("Please input the information of number%d book:\n", i + 1);
		scanf("%s %s %s", &BOOK_ARRAY[i].name, &BOOK_ARRAY[i].author, &BOOK_ARRAY[i].publisher);
	}
	if (WriteFile(File)) {
		ReadFile(File);
	}
	return 0;
}

//将BOOK_ARRAY中的数据写入到WFile当中,若写入成功返回1,不成功返回0
int WriteFile(const char* WFile) {
	FILE* fwt;
	//以写入方式打开WFile,文件指针fwt指向WFile的文件头
	if ((fwt = fopen(WFile, "w")) == NULL) {
		printf("open File error\n");
		return 0;
	}
	for (int i = 0; i < MAXSIZE; i++) {
		//将BOOK_ARRAY写入fwt,每个数据块大小为一个结构体的sizeof,若写入的数据块个数不为1,则报错
		if (fwrite(&BOOK_ARRAY[i], sizeof(book_info), 1, fwt) != 1) {
			printf("write File error\n");
			return 0;
		}
	}
	fclose(fwt);
	return 1;
}

int ReadFile(const char* RFile) {
	FILE* frt;
	//以读取方式打开RFile,文件指针fwt指向WFile的文件头
	if ((frt = fopen(RFile, "r")) == NULL) {
		printf("open File error\n");
		return 0;
	}
	for (int i = 0; i < MAXSIZE; i++) {
		fread(&BOOK_ARRAY[i], sizeof(book_info), 1, frt);
		printf("number:%d\tname:%s\tauthor:%s\tpublisher:%s\n", i + 1, BOOK_ARRAY[i].name, BOOK_ARRAY[i].author, BOOK_ARRAY[i].publisher);
	}
	fclose(frt);
	return 1;
}

例二

题目:合并两个已按递增排序的整数文件成为一个按递增排序的文件

#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[]){
	//读取的第一个文件为fp1,读取的第二个文件为fp2,写入文件为fp3 
	FILE *fp1,*fp2,*fp3;
	if(argc!=4){
		printf("The number of arguments error\n");
		return -1;
	}
	if((fp1 = fopen(argv[1],"r"))==NULL){
		printf("open File1 error\n");
		return -1;
	}
	if((fp2 = fopen(argv[2],"r"))==NULL){
		printf("open File2 error\n");
		return -1;
	}
	if((fp3 = fopen(argv[3],"w+"))==NULL){
		printf("open File3 error\n");
		return -1;
	}
	//fp1中读出的数字为a1,fp2中读出的数字为a2 
	int a1,a2;
	fread(&a1,sizeof(int),1,fp1);
	fread(&a2,sizeof(int),1,fp2);
	while(!feof(fp1)&&!feof(fp2)){
		if(a1<a2){
			fwrite(&a1,sizeof(int),1,fp3);
			fread(&a1,sizeof(int),1,fp1);
		}else{
			fwrite(&a2,sizeof(int),1,fp3);
			fread(&a2,sizeof(int),1,fp2);
		}
	}
	while(!feof(fp1)){
		fwrite(&a1,sizeof(int),1,fp3);
		fread(&a1,sizeof(int),1,fp1);
	}
	while(!feof(fp2)){
		fwrite(&a2,sizeof(int),1,fp3);
		fread(&a2,sizeof(int),1,fp2);
	}
	fclose(fp1);
	fclose(fp2);
	fclose(fp3);
	return 0;
}

在命令行当中输入四个参数,分别为执行程序、读取数据的文件名1、读取数据的文件名2、写入数据的文件名。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值