《C语言程序设计 第4版》笔记和代码 第十三章 文件操作

13.1 二进制文件和文本文件

1 C语言文件有两种类型:文本文件(也称ASCII码文件)和二进制文件,前者将数值型数据的每一位数字作为一个字符以其ASCII码的形式存储,后者以二进制形式存储。

2 文本文件中每一位数字都单独占用一个字节的存储空间,而二进制文件把整个数字作为一个二进制数来存储,并非数值的每一位数字都占用单独的存储空间。

3 文本文件便于被其他程序所读取,但存储空间较大,并且需要转换时间。二进制文件可节省外存空间转换时间,但是不能直接输出其对应的字符形式。

4 字节流就是无论文件内容是什么,一律把数据看成由字节构成的序列。

5 C语言文件又被称为流式文件,因为其对文件的存取以字节为单位,且输入\输出数据流仅受程序控制而不受物理符号的控制。

6 C语言有缓冲型非缓冲型两种文件系统,区别在于缓冲区是由系统自动开辟,还是程序员自己设定。后者没有文件指针

7 缓冲型文件系统中的文件操作,也被称为高级文件操作,具有跨平台可移植的能力,是本章的主要讨论对象。

13.2 文件的打开和关闭

1 函数fopen()用于打开文件,其返回值是一个文件指针,有两个形参,第一个形参表示文件名,可包含路径和文件名两部分,第二个形参表示文件打开方式。

2 FILE是一种在stdio.h中定义的结构体类型,封装了与文件有关的信息。

3 打开方式,其值有r (只读);  w(只写且覆盖原文件); a(只写且在原文件后添加数据); +(读写方式打开); b(打开二进制文件)。

4 文件使用结束后必须关闭文件,用fclose()来关闭一个由fopen()打开的文件。

13.3 按字符读写文件

1 函数fgetc()可用于从一个以只读或读写方式打开的文件上读字符,读取成功后返回该字符,读到文件末尾,则返回EOF。

2 函数fputs()用于将一个字符写到一个文件上。

例13.1见文末

3 可通过检查fopen()的返回值是否为NULL来判断文件是否打开成功。

4 使用getchar()输入字符时,先将所有字符送入缓冲区,直到读到回车换行符后才从缓冲区中逐个读出并赋值给变量ch。

例13.2见文末

5 函数feof()用于检查是否达到文件末尾,当文件位置指针指向文件结束符时,返回非0值,否则返回0值。

例13.3见文末

6 函数fgets()可用于读取文件中的字符串,读取失败时返回空指针

例13.4见文末

7 fgets()从指定的流读字符串,读到换行符时将换行符也作为字符串的一部分读到字符串中,这与gets()函数不同。

8 fputs()不会再写入文件的字符串末尾加上换行符,这与puts()不同。

13.4 按格式读写文件

1 函数fscanf()用于按指定格式从文件读数据,函数fprintf()用于按指定格式向文件写数据。

例13.5和13.6见文末

13.5 按数据块读写文件

1 函数fread()fwrite()用于一次读取一组数据,也就是按数据块读写文件。

2 fread()的功能是从形参fp所指的文件中读取数据块并存储到形参buffer所指的内存中。 函数返回的是实际读到的数据块个数。

3 fwrite()的功能是将形参buffer所指的内存中的数据块写入到形参fp中。函数返回的是实际写入的数据块的个数。

例13.7见文末

代码

13.1

从键盘键入一串字符,然后把它们转存到磁盘文件上

//13.1从键盘键入一串字符,然后把它们转存到磁盘文件上
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
	FILE *fp;
	char ch;
	if((fp=fopen("demo.txt","w"))==NULL)//判断文件是否成功打开
	{
		printf("Failure to open demo.txt!\n");
		exit(0);
	 } 
	ch=getchar();
	while(ch!='\n')//键入回车换行符则结束键盘输入和文件写入 
	{
		fputc(ch,fp);
		ch=getchar(); 
	}
	fclose(fp);//关闭fp指向的文件 
	return 0;
 }

13.2

将0~127之间的ASCII字符写到文件中,然后从文件中读出并显示到屏幕上

//13.2将0~127之间的ASCII字符写到文件中,然后从文件中读出并显示到屏幕上
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
	FILE *fp;
	char ch;
	int i; 
	if((fp=fopen("demo.bin","wb"))==NULL)//以二进制方式打开文件 
	{
		printf("Failure to open demo.bin!\n");
		exit(0);
	 } 
	for(i=0;i<128;i++)
	{
		fputc(i,fp);
	}
	fclose(fp);
	if((fp=fopen("demo.bin","rb"))==NULL)//以二进制方式打开文件 
	{
		printf("Failure to open demo.bin!\n");
		exit(0);
	 }
	while((ch=fgetc(fp))!=EOF)
	{
		putchar(ch);//显示所有字符 
	}
	fclose(fp);
	return 0;
 } 

13.3

将0~127之间的ASCII字符写到磁盘文件中,然后从文件中读出这些字符时,判断是否为可打印字符,是则打印,否则显示其ASCII 

//13.3 将0~127之间的ASCII字符写到磁盘文件中,然后从文件中读出这些字符时,判断是否为可打印字符,是则打印,否则显示其ASCII 
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h> 
int main(void)
{
	FILE *fp;
	char ch;
	int i; 
	if((fp=fopen("demo.bin","wb"))==NULL)//以二进制方式打开文件 
	{
		printf("Failure to open demo.bin!\n");
		exit(0);
	 } 
	for(i=0;i<128;i++)
	{
		fputc(i,fp);
	}
	fclose(fp);
	if((fp=fopen("demo.bin","rb"))==NULL)//以二进制方式打开文件 
	{
		printf("Failure to open demo.bin!\n");
		exit(0);
	 }
	while((ch=fgetc(fp))!=EOF)
	{
		if(isprint(ch))
			printf("%c\t",ch);
		else
			printf("%d\t",ch);
	}
	fclose(fp);
	return 0;
 } 

13.4

用函数fgets()来改写例13.1,从键盘键入一串字符,然后把它们添加到文本文件demo.txt的末尾。

//13.4 用函数fgets()来改写例13.1,从键盘键入一串字符,然后把它们添加到文本文件demo.txt的末尾。
#include<stdio.h>
#include<stdlib.h>
#define N 80
int main(void)
{	FILE *fp;
	char str[N];
	if((fp=fopen("demo.txt","a"))==NULL)//以添加方式打开 
	{
		printf("Failure to open demo.txt!\n");
		exit(0);
	 } 
	gets(str);//从键盘读入字符串
	fputs(str,fp);//将字符串写入fp所指的文件
	fclose(fp); 
	if((fp=fopen("demo.txt","r"))==NULL)//读方式打开
	{
		printf("Failure to open demo.txt!\n");
		exit(0); 
	 } 
	fgets(str,N,fp);
	puts(str);
	fclose(fp);//关闭fp指向的文件 
	return 0;
 }

13.5

修改12.7程序,编程计算每个学生的4门课程的平均分,将学生的各科成绩及平均分输出到文件

 13.5 修改12.7程序,编程计算每个学生的4门课程的平均分,将学生的各科成绩及平均分输出到文件score.txt中
#include<stdio.h>
#include<stdlib.h>
#define N 30 
typedef struct date
{
	int year;
	int month;
	int day;
 }DATE;//别名为DATE
 typedef struct student
 {
 	long studentID;
 	char studentName[10];
 	char studentSex;
 	DATE birthday;//嵌套结构体 
	int score[4]; 
	float aver;//平均分 
  }STUDENT;
void InputScore(STUDENT stu[],int n,int m);
void AverScore(STUDENT stu[],int n,int m);
void WritetoFile(STUDENT stu[],int n,int m);
int main(void)
{
	float aver[N];
	STUDENT stu[N];
	int n;
	printf("How many students?");
	scanf("%d",&n);
	InputScore(stu,n,4);
	AverScore(stu,n,4);
	WritetoFile(stu,n,4);
	return 0;
 }
void InputScore(STUDENT stu[],int n,int m){
	int i,j;
	for(i=0;i<n;i++)
	{
		printf("Input recore %d:\n",i+1);
		scanf("%ld",&stu[i].studentID);
		scanf("%s",stu[i].studentName);//这里无取地址符
		scanf(" %c",&stu[i].studentSex);
		scanf("%d",&stu[i].birthday.year);
		scanf("%d",&stu[i].birthday.month);
		scanf("%d",&stu[i].birthday.day);
		for(j=0;j<m;j++){
			scanf("%d",&stu[i].score[j]);
		}
	}
}
//计算n个学生m课程的平均分 
void AverScore(STUDENT stu[],int n,int m){ 
	int i,j,sum[N];
	for(i=0;i<n;i++)
	{
		sum[i]=0;
		for(j=0;j<4;j++)
		{
			sum[i]=sum[i]+stu[i].score[j]; 
		}
		stu[i].aver=(float)sum[i]/m;
	}
}
void WritetoFile(STUDENT stu[],int n,int m){
	FILE *fp;
	int i,j;
	if((fp=fopen("score.txt","w"))==NULL)
	{
		printf("Failure to open score.txt!\n");
		exit(0);
	}
	fprintf(fp,"%d\t%d\n",n,m);//写入学生人数和课程数
	for(i=0;i<n;i++)
	{
		fprintf(fp,"%10ld%8s%3c%6d/%02d/%02d",
		stu[i].studentID,stu[i].studentName,stu[i].studentSex,
		stu[i].birthday.year,stu[i].birthday.month,stu[i].birthday.day);
		for(j=0;j<m;j++)
		{
			fprintf(fp,"%4d",stu[i].score[j]);
		}
		fprintf(fp,"%6.1f\n",stu[i].aver);
	 } 
	fclose(fp);
}

13.6

在例13.5程序运行结果的基础上,编程从文件score.txt中读出每个学生的信息,并输出到屏幕上。

//例13.6 在例13.5程序运行结果的基础上,编程从文件score.txt中读出每个学生的信息,并输出到屏幕上。
#include<stdio.h>
#include<stdlib.h>
#define N 30 
typedef struct date
{
	int year;
	int month;
	int day;
 }DATE;//别名为DATE
 typedef struct student
 {
 	long studentID;
 	char studentName[10];
 	char studentSex;
 	DATE birthday;//嵌套结构体 
	int score[4]; 
	float aver;//平均分 
  }STUDENT;
void ReadfromFile(STUDENT stu[],int *n,int *m);
void PrintScore(STUDENT stu[],int n,int m);

int main(void)
{
	STUDENT stu[N];
	int n,m=4;
	ReadfromFile(stu,&n,&m);
	PrintScore(stu,n,m);
	return 0;
 }
void ReadfromFile(STUDENT stu[],int *n,int *m){
	FILE *fp;
	int i,j;
	if((fp=fopen("score.txt","r"))==NULL)
	{
		printf("Failure to open score.txt!\n");
		exit(0);
	}
	fscanf(fp,"%d\t%d",n,m);
	for(i=0;i<*n;i++)
	{
		fscanf(fp,"%10ld",&stu[i].studentID);
		fscanf(fp,"%8s",stu[i].studentName);
		fscanf(fp," %c",&stu[i].studentSex);
		fscanf(fp,"%6d/%2d/%2d",&stu[i].birthday.year,
								&stu[i].birthday.month,
								&stu[i].birthday.day);
		for(j=0;j<*m;j++){
			fscanf(fp,"%4d",&stu[i].score[j]);
		}
	fscanf(fp,"%f",&stu[i].aver);//不能使用%6.1f格式 
	}
	fclose(fp);
}

void PrintScore(STUDENT stu[],int n,int m){
	int i,j;
	for(i=0;i<n;i++)
	{
		printf("%10ld%8s%3c%6d/%02d/%02d",
			stu[i].studentID,stu[i].studentName,stu[i].studentSex,//对应学号、姓名、性别 
			stu[i].birthday.year,stu[i].birthday.month,stu[i].birthday.day); //对应出生年月日
		for(j=0;j<m;j++){
			printf("%4d",stu[i].score[j]);
		}
		printf("%6.1f\n",stu[i].aver);
	}
}

13.7

编程计算每个学生的4门课程的平均分,将学生的信息输出到student.txt中,然后再从文件中读出数据并显示到屏幕上。

//13.7编程计算每个学生的4门课程的平均分,将学生的信息输出到student.txt中,然后再从文件中读出数据并显示到屏幕上。
#include<stdio.h>
#include<stdlib.h>
#define N 30 
typedef struct date
{
	int year;
	int month;
	int day;
 }DATE;//别名为DATE
 typedef struct student
 {
 	long studentID;
 	char studentName[10];
 	char studentSex;
 	DATE birthday;//嵌套结构体 
	int score[4]; 
	float aver;//平均分 
  }STUDENT;
void InputScore(STUDENT stu[],int n,int m);
void AverScore(STUDENT stu[],int n,int m);
void WritetoFile(STUDENT stu[],int n);
int ReadfromFile(STUDENT stu[]);
void PrintScore(STUDENT stu[],int n,int m);
int main(void)
{
	STUDENT stu[N];
	int n,m=4;
	printf("How many students?");
	scanf("%d",&n);
	InputScore(stu,n,m);
	AverScore(stu,n,m);
	WritetoFile(stu,n);
	n=ReadfromFile(stu);
	PrintScore(stu,n,m);
	return 0;
 }
void InputScore(STUDENT stu[],int n,int m){
	int i,j;
	for(i=0;i<n;i++)
	{
		printf("Input recore %d:\n",i+1);
		scanf("%ld",&stu[i].studentID);
		scanf("%s",stu[i].studentName);//这里无取地址符
		scanf(" %c",&stu[i].studentSex);
		scanf("%d",&stu[i].birthday.year);
		scanf("%d",&stu[i].birthday.month);
		scanf("%d",&stu[i].birthday.day);
		for(j=0;j<m;j++){
			scanf("%d",&stu[i].score[j]);
		}
	}
}
//计算n个学生m课程的平均分 
void AverScore(STUDENT stu[],int n,int m){ 
	int i,j,sum[N];
	for(i=0;i<n;i++)
	{
		sum[i]=0;
		for(j=0;j<4;j++)
		{
			sum[i]=sum[i]+stu[i].score[j]; 
		}
		stu[i].aver=(float)sum[i]/m;
	}
}
void WritetoFile(STUDENT stu[],int n){
	FILE *fp;
	int i,j;
	if((fp=fopen("student.txt","w"))==NULL)
	{
		printf("Failure to open score.txt!\n");
		exit(0);
	}
	fwrite(stu,sizeof(STUDENT),n,fp);//写入 
	fclose(fp);
}
int ReadfromFile(STUDENT stu[]){
	FILE *fp;
	int i;
	if((fp=fopen("student.txt","r"))==NULL)
	{
		printf("Failure to open score.txt!\n");
		exit(0);
	}
	for(i=0;!feof(fp);i++)
	{
		fread(&stu[i],sizeof(STUDENT),1,fp);//读取
		 
	}
	fclose(fp);
	printf("Total students is %d.\n",i-1);
	return i-1;
}

void PrintScore(STUDENT stu[],int n,int m){
	int i,j;
	for(i=0;i<n;i++)
	{
		printf("%10ld%8s%3c%6d/%02d/%02d",
			stu[i].studentID,stu[i].studentName,stu[i].studentSex,//对应学号、姓名、性别 
			stu[i].birthday.year,stu[i].birthday.month,stu[i].birthday.day); //对应出生年月日
		for(j=0;j<m;j++){
			printf("%4d",stu[i].score[j]);
		}
		printf("%6.1f\n",stu[i].aver);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值