1 C语言文件有两种类型:文本文件(也称ASCII码文件)和二进制文件,前者将数值型数据的每一位数字作为一个字符以其ASCII码的形式存储,后者以二进制形式存储。
2 文本文件中每一位数字都单独占用一个字节的存储空间,而二进制文件把整个数字作为一个二进制数来存储,并非数值的每一位数字都占用单独的存储空间。
3 文本文件便于被其他程序所读取,但存储空间较大,并且需要转换时间。二进制文件可节省外存空间和转换时间,但是不能直接输出其对应的字符形式。
4 字节流就是无论文件内容是什么,一律把数据看成由字节构成的序列。
5 C语言文件又被称为流式文件,因为其对文件的存取以字节为单位,且输入\输出数据流仅受程序控制而不受物理符号的控制。
6 C语言有缓冲型和非缓冲型两种文件系统,区别在于缓冲区是由系统自动开辟,还是程序员自己设定。后者没有文件指针。
7 缓冲型文件系统中的文件操作,也被称为高级文件操作,具有跨平台和可移植的能力,是本章的主要讨论对象。
1 函数fopen()用于打开文件,其返回值是一个文件指针,有两个形参,第一个形参表示文件名,可包含路径和文件名两部分,第二个形参表示文件打开方式。
2 FILE是一种在stdio.h中定义的结构体类型,封装了与文件有关的信息。
3 打开方式,其值有r (只读); w(只写且覆盖原文件); a(只写且在原文件后添加数据); +(读写方式打开); b(打开二进制文件)。
4 文件使用结束后必须关闭文件,用fclose()来关闭一个由fopen()打开的文件。
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()不同。
1 函数fscanf()用于按指定格式从文件读数据,函数fprintf()用于按指定格式向文件写数据。
例13.5和13.6见文末
1 函数fread()和fwrite()用于一次读取一组数据,也就是按数据块读写文件。
2 fread()的功能是从形参fp所指的文件中读取数据块并存储到形参buffer所指的内存中。 函数返回的是实际读到的数据块个数。
3 fwrite()的功能是将形参buffer所指的内存中的数据块写入到形参fp中。函数返回的是实际写入的数据块的个数。
例13.7见文末
从键盘键入一串字符,然后把它们转存到磁盘文件上
//13.1从键盘键入一串字符,然后把它们转存到磁盘文件上 #include #include 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; } 将0~127之间的ASCII字符写到文件中,然后从文件中读出并显示到屏幕上
//13.2将0~127之间的ASCII字符写到文件中,然后从文件中读出并显示到屏幕上 #include #include 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; } 将0~127之间的ASCII字符写到磁盘文件中,然后从文件中读出这些字符时,判断是否为可打印字符,是则打印,否则显示其ASCII
//13.3 将0~127之间的ASCII字符写到磁盘文件中,然后从文件中读出这些字符时,判断是否为可打印字符,是则打印,否则显示其ASCII #include #include #include 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; } 用函数fgets()来改写例13.1,从键盘键入一串字符,然后把它们添加到文本文件demo.txt的末尾。
//13.4 用函数fgets()来改写例13.1,从键盘键入一串字符,然后把它们添加到文本文件demo.txt的末尾。 #include #include #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; } 修改12.7程序,编程计算每个学生的4门课程的平均分,将学生的各科成绩及平均分输出到文件
13.5 修改12.7程序,编程计算每个学生的4门课程的平均分,将学生的各科成绩及平均分输出到文件score.txt中 #include #include #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 在例13.5程序运行结果的基础上,编程从文件score.txt中读出每个学生的信息,并输出到屏幕上。
//例13.6 在例13.5程序运行结果的基础上,编程从文件score.txt中读出每个学生的信息,并输出到屏幕上。 #include #include #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 编程计算每个学生的4门课程的平均分,将学生的信息输出到student.txt中,然后再从文件中读出数据并显示到屏幕上。
//13.7编程计算每个学生的4门课程的平均分,将学生的信息输出到student.txt中,然后再从文件中读出数据并显示到屏幕上。 #include #include #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