文件操作

文件操作方法

fread和fwrite

文件的操作分为两种

1.把内存里一组连续存储区的内容拷贝到文件里(写文件)

2.把文件里一组连续存储区的内容拷贝到内存里(读文件)

fread函数可以采用二进制的方式对文件进行读操作;fwrite函数可以采用二进制的方式对文件进行写操作。

这两个函数都需要四个参数:

1.内存里第一个存储区的地址

2.内存里单个存储区的大小

3.希望操作的存储区个数

4.文件指针

返回值表示实际操作的存储区个数,

/*
 *fwrite
 * */
#include<stdio.h>
int main (){
	int arr[] = {1,2,3,4,5},size = 0;
	FILE *p_file = fopen("a.bin","wb");
	if (p_file){
		size = fwrite(arr,sizeof(int),5,p_file);
		printf("size = %d\n",size);
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}
/*
 *fread
 * */
#include<stdio.h>
int main (){
	int arr[5] = {0},size = 0,num = 0;
	FILE *p_file = fopen("a.bin","rb");
	if (p_file){
		size = fread(arr,sizeof(int),10,p_file);
		printf("size = %d\n",size);
		for (num = 0;num <= 4;num++){
			printf("%d ",arr[num]);
		}
		printf("\n");
		fclose(p_file);
		p_file = NULL;
	}
	return 0;

练习:编写程序把以下二维数组里的所有数字记录到二进制文件里

11111

22222

33333

44444

55555

/*
 *
 *文件操作练习
 *
 * */
#include<stdio.h>
int main (){
	int size = 0,num = 0;
	int arr[][5] = {1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5};
	FILE *p_file = fopen("b.bin","wb");
	if (p_file){

		/*size = fwrite(arr,sizeof(int),25,p_file);
		printf("size = %d\n",size);*/

		for(num = 0;num <= 4;num++){
			fwrite(arr[num],sizeof(int),5,p_file);
		}
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

编写程序从上一个程序产生的文件里获得所有数字并按照以下格式显示在屏幕上

55555

44444

33333

22222

11111

/*
 *
 *
 *文件操作练习
 *
 * */
#include<stdio.h>
int main (){
	int arr[5][5] = {0},num = 0;
	int row = 0,col = 0;
	FILE *p_file = fopen("b.bin","rb");
	if (p_file){
		for (num = 4;num >= 0;num--){
			fread(arr[num],sizeof(int),5,p_file);
		}
		for (row = 0;row <= 4;row++){
			for (col = 0;col <= 4;col++){
				printf("%d ",arr[row][col]);
			
			}
			printf("\n");
		
		}
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

文本文件操作

/*
 *文本文件演示
 *
 * */
#include<stdio.h>
#include<string.h>
int main (){
	char buf[20] = {0};
	int num = 0;
	int arr[] = {1,22,333,4444,55555};
	FILE *p_file = fopen("c.txt","wb");
	if (p_file){
		for (num = 0;num <= 4;num++){
			sprintf(buf,"%d ",arr[num]);
			fwrite(buf,sizeof(char),strlen(buf),p_file);
		}
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

以下两个函数以文本方式操作文件

fprintf

fprintf函数可以按照规定的格式把数字记录到文本文件里,fprintf函数的第一个参数是文件指针,后面的参数就是printf函数的参数。

/*
 *文件练习
 *
 * */
#include<stdio.h>
int main (){
	int num = 0;
	int arr[] = {1,22,333,4444,55555};
	FILE *p_file = fopen("d.txt","w");
	if (p_file){
		for (num = 0;num <= 4;num++){
			fprintf(p_file,"%d",arr[num]);
		}
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

fscanf

fscanf函数可以从文本文件里获得数字并记录到存储区里,scanf函数的第一个参数是文件指针,后面的参数就是scanf函数的参数。

/*
 *
 *文件操作练习
 * */
#include<stdio.h>
int main (){
	int num = 0,val = 0;
	FILE *p_file = fopen("d.txt","r");
	if (p_file){
		for (num = 0;num <= 4;num++){
			fscanf(p_file,"%d",&val);
			printf("val = %d\n",val);
		}
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

这两个函数不适合处理包含大量数据的文件

练习:编写程序从键盘得到多个考试成绩并把他们记录到文本文件里,考试成绩的个数不确定。

/*
 *文件练习
 *
 * */
#include<stdio.h>
int main (){
	int grade = 0;
	FILE *p_file = fopen("e.txt","w");
	if (p_file){
		while (1){
			printf("请输入一个考试成绩:");
			scanf("%d",&grade);
			if (grade < 0 || grade > 100){
				break;
			}
			fprintf(p_file,"%d ",grade);
		}
		fprintf(p_file,"%d",-1);
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

练习:编写程序从上一个程序制作的文件里获得所有考试成绩并计算他们的和,把求和结果显示在屏幕上。

/*
 *
 *文本文件操作
 * */
#include<stdio.h>
int main (){
	int grade = 0,sum = 0;
	FILE *p_file = fopen("e.txt","r");
	if (p_file){
		while (1){
			fscanf(p_file,"%d ",&grade);
			if (grade < 0 || grade > 100){
				break;
			}
			sum += grade;
		}
		printf("sum = %d\n",sum);
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

练习:编写模拟人员信息管理系统

每次运行程序的时候可以记录用户输入的多个人员信息,每个人员信息包含整数类型ID,单精度浮点类型的工资以及姓名人员信息要求记录在二进制文件里而且文件内容可以拓展。

/*
 *人员信息管理系统
 *
 * */
#include<stdio.h>
#include<string.h>
typedef struct{
	int id;
	float salary;
	char name[10];
}person;
int main (){
	int choice = 0;
	person prsn = {0};
	FILE *p_file = fopen("person.bin","ab");
	if (p_file){
		while (1){
			printf("请输入人员ID:");
			scanf("%d",&(prsn.id));
			printf("请输入工资:");
			scanf("%g",&(prsn.salary));
			scanf("%*[^\n]");
			scanf("%*c");
			printf("请输入姓名:");
			fgets(prsn.name,10,stdin);
			if (strlen(prsn.name) == 9 && prsn.name[8] != '\n'){
				scanf("%*[^\n]");
				scanf("%*c");
			}
			fwrite(&prsn,sizeof(person),1,p_file);
			printf("是否需要输入下一个人员信息?0表示不需要,1表示需要。");
			scanf("%d",&choice);
			if (!choice){
				break;
			}
		}
		fclose (p_file);
		p_file =NULL;
	}
	return 0;
}

练习:将人员信息显示在屏幕上

/*
 *
 *人员信息管理系统
 *
 * */
#include<stdio.h>
typedef struct {
	int id;
	float salary;
	char name[10];
}person;
int main (){
	int size = 0;
	person prsn = {0};
	FILE *p_file = fopen("person.bin","rb");
	if (p_file){
		while (1){
			size = fread(&prsn,sizeof(person),1,p_file);
			if (!size){
				break;
			}
			printf("ID:%d\n",prsn.id);
			printf("工资为:%g\n",prsn.salary);
			printf("name:%s\n",prsn.name);
		}
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

文件的位置指针

计算机里为每个打开的文件保留一个整数,这个整数决定下一次读写操作的开始位置,这个位置一定在两个相邻字节之间,这个整数就是文件头到这个位置之间包含的字节个数,这个整数叫做文件的位置指针,每当从文件里获得n个字节或向文件里写入n个字节后位置指针都会向后移动n个字节。

/*
 *
 *位置指针演示
 *
 * */
#include<stdio.h>
int main (){
	char ch = 0;
	FILE *p_file = fopen("abc.txt","rb");
	if (p_file){
		fread(&ch,sizeof(char),1,p_file);
		printf("ch = %c\n",ch);
		fread(&ch,sizeof(char),1,p_file);
		printf("ch = %c\n",ch);
		fread(&ch,sizeof(char),1,p_file);
		printf("ch = %c\n",ch);
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

ftell

ftell函数可以获得位置指针的数值

rewind

rewind函数可以把位置指针设定到文件开头

fseek

fseek函数可以把位置指针设置到文件里的任何位置,使用fseek函数的时候需要指定一个基准位置和目标位置到基准位置之间的距离。

SEEK_SET 0 把文件头作为基准位置

SEEK_CUR 1 把当前位置作为基准位置

SEEK_END 2 把文件尾作为基准位置

如果目标位置在基准位置后边则距离用非负数表示,如果目标位置在基准位置前边则距离用负数表示。距离的绝对值就是两个字节之间包含的字节个数。

/*
 *
 *位置指针演示
 *
 * */
#include<stdio.h>
int main (){
	char ch = 0;
	FILE *p_file = fopen("abc.txt","rb");
	if (p_file){
		printf("%ld\n",ftell(p_file));
		fread(&ch,sizeof(char),1,p_file);
		printf("ch = %c\n",ch);
		//rewind(p_file);
		fseek(p_file,2,SEEK_SET);

		printf("%ld\n",ftell(p_file));
		fread(&ch,sizeof(char),1,p_file);
		printf("ch = %c\n",ch);
		//rewind(p_file);
		fseek(p_file,4,SEEK_CUR);

		printf("%ld\n",ftell(p_file));
		fread(&ch,sizeof(char),1,p_file);
		printf("ch = %c\n",ch);
		//rewind(p_file);
		fseek(p_file,-3,SEEK_END);

		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}

练习:编写程序从person.bin文件里获得所有人的id并把它们都显示在屏幕上

/*
 *人员信息ID
 *
 * */
#include<stdio.h>
typedef struct {
	int id;
	float salary;
	char name[10];
}person;
int main (){
	int id = 0,size = 0;
	FILE *p_file = fopen("person.bin","rb");
	if (p_file){
		while (1){
			size = fread(&id,sizeof(int),1,p_file);
			if (!size){
				break;
			}
			printf("ID = %d\n",id);
			fseek(p_file,sizeof(person) - sizeof(int),SEEK_CUR);
		}
		fclose(p_file);
		p_file = NULL;
	}
	return 0;
}