C程序设计(谭浩强)第五版课后题答案 第十章
1.什么是文件型指针?通过文件指针访问文件有什么好处?
答:缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的有关信息(如文件的名字、文件状态及文件当前位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名为FILE。
通过文件指针访问文件的好处是:可以随机访问文件,有效表示数据结构,动态分配内存,方便使用字符串,有效使用数组。
2.对文件的打开与关闭的含义是什么?为什么要打开和关闭文件?
答:”打开“是指为文件建立相应的信息区(用来存放有关文件的信息)和文件缓冲区(用来暂时存放输入输出的数据)。
”关闭“是指撤销文件信息区和文件缓冲区,使文件指针变量不再指向该文件,显然就无法进行对文件的读写了。
3.从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,然后输出到一个磁盘文件test中保存,输入的字符串以“!”结束。
#include <stdio.h> #include<string.h> #include<stdlib.h> int main(void) { FILE *fp; char str[100]; int i=0; if((fp=fopen("text","w"))==NULL) { printf("open file text error!\n"); exit(0); } printf("请输入字符串:\n"); gets(str); while(str[i]!='!') { if(str[i]>='a' && str[i]<='z') str[i]=str[i]-'a' + 'A'; fputc(str[i],fp); i++; } fclose(fp); fp=fopen("text","r"); fgets(str,strlen(str)+1,fp); printf("%s\n",str); fclose(fp); return 0; }
4.有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件C中去。
#include <stdio.h> #include<stdlib.h> #include<string.h> int main(void) { FILE *fa,*fb,*fc; char a[1024]={0}; int len=strlen(a); void select_sort(char *); fa=fopen("A","r"); fb=fopen("B","r"); fc=fopen("C","w"); fgets(a,1024,fa); //从指定的流 fa 读取一行,并把它存储在 a 所指向的字符串内。 fgets(a+len,1024-len,fb); //当读取 (1024-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止, select_sort(a); fputs(a,fc); fclose(fa); fclose(fb); fclose(fc); } void select_sort(char *str) { int i,j,min; int len=strlen(str); void swap(char *,int,int); for(i=0;i<len;i++) { min=i; for(j=i+1;j<len;j++) { if(str[j]<str[min]) min=j; } swap(str,min,j); } } void swap(char *str,int i,int j) { char t=str[i]; str[i]=str[j]; str[j]=t; }
5.有5个学生,每个学生有3门课程的成绩,从键盘输入学生数据(包括学号,姓名,3门课程成绩),计算出平均成绩,将原有数据和计算出的平均分数存放在磁盘文件stud中。
#include <stdio.h> #include<stdlib.h> struct student { int num; char name[40]; int score[3]; float avg; }; int main(void) { int i; struct student stu[5]; FILE *fp=NULL; printf("按以下格式输入各名同学的成绩\n"); printf("num name score1 score2 score3\n"); for(i=0;i<5;i++) { scanf("%d%s%d%f",&stu[i].num,&stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]); stu[i].avg=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0; } if((fp=fopen("stud","wb"))==NULL) { printf("open file stu for write error\n"); exit(0); } if(fwrite(stu,sizeof(stu),1,fp)!=1) //将缓冲区stu中的内容写到流fp中,每块的大小为sizeof(stu),块数为1,返回值为实际写出块数 { printf("write error!\n"); return 1; } fclose(fp); }
6.将第5题stud文件中的学生数据,按平均分进行排序处理,将已排序的学生数据存入一个新文件stu_ sort 中。
#include <stdio.h> #include<stdlib.h> struct student { int num; char name[40]; int score[3]; float avg; }; int main(void) { struct student stu[5]; void sort(struct student[],int); FILE *fp,*fw; fp=NULL; if((fp=fopen("stud","rb"))==NULL) { printf("open file stu for write error\n"); exit(0); } if(fread(stu,sizeof(stu),1,fp)!=1) //从流fp中读取内容写到缓冲区stu中,每块的大小为sizeof(stu),块数为1,返回值为实际写出块数 { printf("write error!\n"); return 1; } fclose(fp); sort(stu,5); fw=fopen("stu_sort","wb"); fwrite(stu,sizeof(stu),1,fw); fclose(fw); return 0; } void sort(struct student stu[],int len) { int i,j,min; struct student temp; for(i=0;i<len;i++) { min=i; for(j=i+1;j<len;j++) { if(stu[j].avg<stu[min].avg) min=j; } temp=stu[min]; stu[min]=stu[i]; stu[i]=temp; } }
7.将第6题已排序的学生成绩文件进行插入处理。插入一个学生的3门课程成绩,程序先计算新插入学生的平均成绩,然后将它按成绩高低顺序插入,插入后建立一个新文件。
#include <stdio.h> #include<stdlib.h> #include<string.h> struct student { int num; char name[40]; int score[3]; float avg; }; int main(void) { struct student stu[5]; struct student new_stu[6]; void sort(struct student[],int); FILE *fp,*fw; fp=NULL; if((fp=fopen("stud","rb"))==NULL) { printf("open file stu for write error\n"); exit(0); } if(fread(stu,sizeof(stu),1,fp)!=1) { printf("read error!\n"); return 1; } fclose(fp); memcpy(new_stu,stu,sizeof(stu)); printf("请按以下格式输入第6名同学的信息\n"); printf("num name score1 score2 score3\n"); scanf("%d %s %d %d %d",&new_stu[5].num,&new_stu[5].name,&new_stu[5].score[0],&new_stu[5].score[1],&new_stu[5].score[2]); new_stu[5].avg=(new_stu[5].score[0]+new_stu[5].score[1]+new_stu[5].score[2])/3.0; sort(new_stu,6); fw=fopen("tmp_sort","wb"); fwrite(new_stu,sizeof(new_stu),1,fw); fclose(fw); return 0; } void sort(struct student stu[],int len) { int i,j,min; struct student temp; for(i=0;i<len;i++) { min=i; for(j=i+1;j<len;j++) { if(stu[j].avg<stu[min].avg) min=j; } temp=stu[min]; stu[min]=stu[i]; stu[i]=temp; } }
8.将第7题结果仍存入原有的stu_sort 文件而不另建立新文件。
#include <stdio.h> #include<stdlib.h> #include<string.h> struct student { int num; char name[40]; int score[3]; float avg; }; int main(void) { struct student stu[6]; FILE *fp,*fw; fp=NULL; if((fp=fopen("stud","rb"))==NULL) { printf("open file stu for write error\n"); exit(0); } if(fread(stu,sizeof(stu),1,fp)!=1) { printf("read error!\n"); return 1; } fclose(fp); fw=fopen("stu_sort","wb"); fwrite(stu,sizeof(stu),1,fw); fclose(fw); return 0; }
9.有一磁盘文件employee,内存放职工的数据。每个职工的数据包括职工姓名、职工号、性别、年龄、住址、工资、健康状况、文化程度。今要求将职工名、工资的信息单独抽出来另建一个简明的职工工资文件。
#include <stdio.h> #include<stdlib.h> #include<string.h> struct employee { int num; char name[40]; char sex[4]; int age; char addr[80]; int salary; char health[10]; char clas[10]; }; struct nasa{ char name[40]; int salary; }; int main(void) { int i; FILE *fp1,*fp2; struct employee employee_n1[5]; struct nasa nasa_n2[5]; fp1=open("employee","rb"); fread(employee_n1,sizeof(employee_n1),1,fp1); fclose(fp1); for(i=0;i<5;i++) { strcpy(nasa_n2[i].name,employee_n1[i].name); nasa_n2[i].salary=employee_n1[i].salary; } fp2=open("nasa","rb"); fwrite(nasa_n2,sizeof(nasa_n2),1,fp2); fclose(fp2); return 0; }
10.从第9题的“职工工资文件”中删去一个职工的数据,再存回原文件。
#include <stdio.h> #include<stdlib.h> #include<string.h> struct nasa{ char name[40]; int salary; }; int main(void) { int i; FILE *fp; struct nasa nasa_n[5]; char name[40]; fp=open("nasa","rb"); fwrite(nasa_n,sizeof(nasa_n),1,fp); fclose(fp); printf("请输入要删去的名字:\n"); scanf("%s",name); fp=open("nasa","wb"); for(i=0;i<5;i++) { if(strcmp(nasa_n[i].name,name)==0) continue; fwrite(&nasa_n,sizeof(nasa_n),1,fp); } fclose(fp); return 0; }
11.从键盘输入若干行字符(每行长度不等),输入后把它们存储到一磁盘文件中。再从该文件中读入这些数据,将其中小写字母转换成大写字母后在显示屏上输出。
#include<stdio.h> #include<stdlib.h> int main() { int i,flag; char str[80],c; FILE *fp; fp=fopen("text.txt","w"); //注意fopen写成open了不会报错,但会运行崩溃 flag=1; while(flag==1) { printf("Input string:"); gets(str); fprintf(fp,"%s",str); //把字符串str按%s的格式输出到fp指向的文件text中 printf("输入N或结束循环,输入其他字符结束循环:"); c=getchar(); getchar(); //吸收回车产生的换行符 if((c=='N')||(c=='n')) flag=0; printf("\n"); } fclose(fp); fp=fopen("text.txt","r"); printf("转换后的字符串为:"); while(fscanf(fp,"%s",str)!=EOF) //从fp指向的磁盘文件text中读取字符串送给字符串str { for(i=0;str[i]!='\0';i++) { if((str[i]>='a')&& (str[i]<='z')) str[i]=str[i]-32; } printf("%s",str); } printf("\n"); fclose(fp); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探