【练习12-1】读出例12-1学生成绩文件f12-1.txt内容,输出最高分和最低分及相应的学号和姓名。
解答:
#include #include struct student{ long num; char stname[20]; int score; }; int main(void) { FILE *fp; int i,max,min,j=0,k=0; struct student students[5]; if((fp=fopen(\"f12-1.txt\ printf(\"File open error!\\n\"); exit(0); } fscanf(fp,\"%ld%s%d\e); max=min=students[0].score; for(i=1;i<=4;i++){ fscanf(fp,\"%ld%s%d\ if(max j=i; } if(min>students[i].score){ min=students[i].score; k=i; } } printf(\"Max score: %d,num:%d,name:%s\\n\j].score,students[j].num,&students[j].stname); printf(\"Min score: %d,num:%d,name:%s\\n\ame); if(fclose(fp)){ printf(\"Can not close the file!\\n\"); exit(0); } return 0; } 【练习12-2】请使用例8-9答电码加密函数对民吗字符串进行加密,改写例12-2。 解答: #include #include #include struct sysuser{ char username[20]; char password[8]; }; void encrypt(char *pwd); int main(void) { FILE *fp; int i; struct sysuser su; if((fp=fopen(\"f12-2.txt\ printf(\"File open error!\\n\"); exit(0); } for(i=1;i<=5;i++){ printf(\"Enter %dth sysuser (name password):\ scanf(\"%s%s\ encrypt(su.password); fprintf(fp,\"%s %s\\n\ } if(fclose(fp)){ printf(\"Can not close the file!\\n\"); exit(0); } return 0; } void encrypt(char *pwd) { int i; for(i=0;i pwd[i]='a'; else pwd[i]+=1; } 【练习12-3】例12-3中为什么在执行fputc(ch,fp2)前要判断ch的值是否等于EOF?改写例12-3的程序,在复制用户信息文件后,再统计被复制文件中字符的数量。 解答: 文件结束符EOF是一个值为-1的常量,读文件时可用来判断从文件中读入的字符是否为EOF来决定循环是否继续。 #include #include int main(void) { FILE *fp1,*fp2; char ch; int count=0; if((fp1=fopen(\"f12-2.txt\ printf(\"File open error!\\n\"); exit(0); } if((fp2=fopen(\"f12-3.txt\ printf(\"File open error!\\n\"); exit(0); } while(!feof(fp1)){ ch=fgetc(fp1); if(ch!=EOF) { fputc(ch,fp2); count++; } } if(fclose(fp1)){ printf(\"Can not close the file!\\n\"); exit(0); } if(fclose(fp2)){ printf(\"Can not close the file!\\n\"); exit(0); } printf(\"f12-2中字符数量为:%d\ return 0; } 【练习12-4】字母转换并统计行数: 读取一个指定的文本文件,显示在屏幕上,如果有大写字母,则改成小写字母再输出,并根据回车符统计行数。试编写相应程序。 解答: #include #include int main(void) { char ch; int countline=0; FILE *fp; if((fp=fopen(\"练习12-4.txt\ printf(\"Not open!\"); exit(0); } while(!feof(fp)){ ch=fgetc(fp); if(ch!=EOF) if(ch>='A'&&ch<='Z') printf(\"%c\ else printf(\"%c\ if(ch=='\\n') countline++; } printf(\"\\n\"); printf(\"file's line is:%d.\ if(fclose(fp)){ printf(\"Can not close!\"); exit(0); } return 0; } 【练习12-5】写字符并验证: 从键盘输入一行字符,写入到文件f3.txt中,并重新读出,最终在屏幕上显示验证。程序输入以读到回车符“\\n”为结束,读文件时要用EOF来控制循环。试编写相应程序。 解答: #include #include int main(void) { FILE *fp; char ch; if((fp=fopen(\"f3.txt\ printf(\"can not open file!\"); exit(0); } printf(\"Input the string:\\n\"); ch=getchar(); while(ch!='\\n'){ fputc(ch,fp); ch=getchar(); } rewind(fp); while(!feof(fp)){ ch=fgetc(fp); if(ch!=EOF) putchar(ch); } printf(\"\\n\"); if(fclose(fp)){ printf(\"can not close file!\\n\"); exit(0); } return 0; } 【练习12-6】实数取整写入文件: 文件f1.txt中有若干个实数,请分别读出,将每个实数按四舍五入取整后存入文件f2.txt中。试编写相应程序。 解答: #include #include int main(void) { FILE *fp1,*fp2; double a; if((fp1=fopen(\"f1.txt\ printf(\"File open error!\\n\"); exit(0); } if((fp2=fopen(\"f2.txt\ printf(\"File open error!\\n\"); exit(0); } while(!feof(fp1)){ fscanf(fp1,\"%lf\ fprintf(fp2,\"%.0f \ } if(fclose(fp1)){ printf(\"Can not close the file!\\n\"); exit(0); } if(fclose(fp2)){ printf(\"Can not close the file!\\n\"); exit(0); } return 0; } 【练习12-7】修改例12-6,增加修改资金账户的功能。输入一个记录ID,如果文件中已存在该记录,则输入新的记录信息并更新资金账户文件中相应记录的信息。要求定义和调用函数UpdateLog(),其功能是修改资金账户记录。 解答: #include #include long size; struct LogData{ long logid; char logdate[11]; char 1ognote[15]; double charge; double balance; }; int inputchoice() { int mychoice; printf(\"\\nEnter your choice: \\n\"); printf(\"1-Add a new cash LOG.\\n2-List All Cash LOG.\\n\"); printf(\"3-Query Last Cash LoG.\\n0-End program.\\n\"); scanf(\"%d\ return mychoice; } long getLogcount(FILE *cfptr) { long begin,end,logcount; fseek(cfptr,OL,SEEK_SET); begin=ftell(cfptr); fseek(cfptr,size,SEEK_END); end=ftell(cfptr); logcount=(end-begin)/size-1; return logcount; } /*列出所有收支流水账*/ void ListAllLog(FILE *cfptr) { struct LogData log; fseek(cfptr,OL,SEEK_SET); fread(&log,size,1,cfptr); printf(\"logid logdate lognote charge balance \\n\"); while(!feof(cfptr)){ printf(\"%6ld%-11s%-15%10.2lf%10.2lf\\n\arge,log.balance); fread(&log,size,1,cfptr); }; } /*查询显示最后一条记录*/ void QueryLastLog(FILE *cfptr) { struct LogData log; long logcount; logcount=getlogcount(cfptr); if(1ogcount>0) { fseek(cfptr,size*(logcount-1),SEEK_SET); fread(&log,size,1,cfptr); printf(\"The last log is:\\n\"); printf(\"logid:%-6ld\\nlogdate:%-11s\\nlognote:%-15s\\n\ognote); printf(\"charge:%-10.2lf\\nbalance:-10.2lf\\n\ } else printf(\"no logs in file!\\n\"); } /*添加新记录*/ void AddNewLog(FILE *cfptr) { struct LogData log,lastlog; long logcount; printf(\"Input logdate (format: 2006-01-01):\"); scanf(\"%s\ printf(\"Input lognote:\"); scanf(\"%s\ printf(\"Input Charge: Income+and epend-:\"); scanf(\"%lf\ logcount=getLogcount(cfptr); if(logcount>0){ fseek(cfptr,size*(logcount-1),SEEK_SET); fread(&lastlog,size,1,cfptr) log.logid=lastlog.1ogid+1; log.balance=log.charge+lastlog.balance; } else{ log.logid=1; log.balance=log.charge; } rewind(cfptr);ogid=last-taraetlastlog; printf(\"logid=%ld\\n\ fwirte(&log,sizeof(struct LogData),1,cfptr); } /*修改资金账户*/ void UpdateLog(FILE *cfptr) { FILE *fpout; struct LogData user; char date[11]; char note[15]; double charge; double balance; int choice,ID; cfptr=fileopen(\"r\"); if((fpout=fopen(\"cash.dat\ printf(\"can not open the file !\\n\"); exit(0); } printf(\"Enter LogID:\"); scanf(\"%d\ while(!feof(cfptr)){ fread(&user,sizeof(struct LogData),1,cfptr); if(strcmp(user.logid,ID)==0){ printf(\"请输入修改信息:\\n\"); printf(\"Date:\"); scanf(\"%s\ strcpy(user.logdate,date); printf(\"Note:\"); scanf(\"%s\ strcpy(user.lognote,note); printf(\"Charge:\"); user.charge=charge; printf(\"Balance:\"); scanf(\"%s\ user.balance=balance; fwrite(&user,sizeof(struct LogData),1,fpout); } else fwrite(&user,sizeof(struct LogData),1,fpout); } if(fclose(cfptr)){ printf(\"can not close file!\\n\"); exit(0); } if(fclose(fpout)){ printf(\"can not close file!\\n\"); exit(0); } unlink(\"cashbox.dat\");//remove(\"cashbox.dat\");都是删除文件的函数 rename(\"cash.dat.dat\ } /*打开文件*/ FILE *openfile(char *openmode) { FILE *fp; if((fp=fopen(\"cashbox.dat\ printf(\"can not open file cashbox.dat!\\n\"); exit(0); } return (fp); } int main(void) { FILE *fp; int choice; size=sizeof(struct LogData); while((choice=inputchoice())!=0){ switch(choice){ case 1: fp=openfile(\"ab+\"); AddNewLog(fp); break; /*列出所有的收入支出情况*/ case 2: fp=openfile(\"rb\"); ListAllLog(fp); break; /*查询最后记录及余额*/ case 3: fp=openfile(\"rb\"); QueryLastLog(fp); break; case 4: fp=openfile(\"rb\"); UpdateLog(fp); break; default: printf(\"Input Error.\"); break; } } if(fclose(fp)){ printf(\"Can not close the file!\\n\"); exit(0); } return 0; } 习题12 一、选择题 1 .以下语句将输出____B_____。 #include printf (\"%d %d %d\‘\\0',EOF); A.0 0 1 B.0 0 -1 C.NULL EOF D.1 0 EOF 2.如果二进制文件a.dat 已经存在,现在要写入全新数据,应以____B____方式打开。 A.\"w\" B.\"wb\" C.\"w+\" D.“wb+\" 3.定义”FILE *fp;\则文件指针fp 指向的是_____D_____。 A.文件在磁盘上的读写位置 B文件在级冲区上的读写位置 C.整个磁盘文件 D.文件类型结构 4.缓冲文件系统的文件缓冲区位于____C______。 A.磁盘缓冲区中 B.磁盘文件中 C.内存数据区中 D.程序文件中 5.使文件指针重新定位到文件读写的首地址的函数是_____C_____。 A.ftell ( ) B.fseek ( ) C.rewind ( ) D.ferror( ) 二、填空题 1.函数fopen ( )的返回值是_指向文件缓冲区的首地址的文件结构类型指针_。 2.文件的三大特征是__名称__、__大小__和__类型__。 3.缓冲文件系统与非缓冲文件系统的不同点在于__系统是否为文件自动分配一块文件缓冲区(内存单元)__。 4.只能向指定文件写入一个字符的函数是_____fputc()函数______。 5.判断文件指针是否已经到了文件尾部的函数是___feof()函数___。 6.阅读程序,以下程序完成的功能是__文件infile内容复制到文件__。 #include int main (void) { char infile [10],outfile [10]; FILE * fpa,* fpb; gets (infile); gets (outfile); fpa=fopen (infile,\"r\" ); fpb=fopen (outfile,\" w\" ); while (! feof (fpa) ) fputc(fgetc(fpa),fpb); fclose (fpa) ; fclose (fpb) ; return 0; } 三、程序设计题 1.统计文本文件中各类字符个数: 分别统计一个文本文件中字母、数字及其他字符的个数。试编写相应程序。 解答: #include #include int main(void) { FILE *fp; char ch; int letter=0,digiter=0,other=0; if((fp=fopen(\"12-3.1.txt\ printf(\"File open error!\\n\"); exit(0); } while((ch=fgetc(fp))!=EOF){ if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z') letter++; else if(ch>='0'&&ch<='9') digiter++; else other++; } printf(\"letter=%d,digiter=%d,other=%d\ if(fclose(fp)){ printf(\"Can not close the file!\\n\"); exit(0); } return 0; } 2.将实数写入文件: 从键盘输人若干实数(以特殊数值-1结束),分别写到一个文本文件中。试编写相应程序。 解答: #include #include int main(void) { FILE *fp; int number; if((fp=fopen(\"12-3.2.txt\ printf(\"can not open file!\\n\"); exit(0); } printf(\"Input number:\\n\"); scanf(\"%d\ while(number!=-1){ fprintf(fp,\"%d\ scanf(\"%d\ } if(fclose(fp)){ printf(\"Can not close the file!\\n\"); exit(0); } return 0; } 3.比较两个文本文件是否相等: 比较两个文本文件的内容是否相同,并输出两个文件中第一次出现不同字符内容的行号及列值。试编写相应程序。 解答: #include #include int main(void) { FILE *fp1,*fp2; int i=1,j=1; char ch1,ch2; if((fp1=fopen(\"12-3.3.1.txt\ printf(\"can not open file!\\n\"); exit(0); } if((fp2=fopen(\"12-3.3.2.txt\ printf(\"can not open file!\\n\"); exit(0); } ch1=fgetc(fp1); ch2=fgetc(fp2); while(ch1!=EOF&&ch2!=EOF){ if(ch1!=ch2) break; else if(ch1!='\\n'){ j++; ch1=fgetc(fp1); ch2=fgetc(fp2); } else{ i++; j=1; ch1=fgetc(fp1); ch2=fgetc(fp2); } } printf(\"首次不同的字符在第%d行、第%d列。\\n\ if(fclose(fp1)){ printf(\"can not close file!\\n\"); exit(0); } if(fclose(fp2)){ printf(\"can not close file!\\n\"); exit(0); } } 4.将文件中的数据求和并写入文本文件尾: 文件Int_Data.dat 中存放了若干整数,将文件中所有数据相加,并把累加和写入该文件的最后。试编写相应程序。 解答: #include #include int main(void) { FILE *fp; int x,sum=0; if((fp=fopen(\"Int_Date.dat\ printf(\"can not open file!\"); exit(0); } while(!feof(fp)){ fscanf(fp,\"%d\ sum+=x; } fprintf(fp,\" %d\ if(fclose(fp)){ printf(\"can not close the file!\\n\"); exit(0); } return 0; } 5.输出含for的行: 将文本文件test.txt 中所有包含字符串“for”的行输出。试编写相应程序。 解答: #include #include #include char s[999]; int main(void) { FILE* fp; int i; if((fp=fopen(\"test.txt\ printf(\"can not open file!\\n\"); exit(0); } while(!feof(fp)){ fgets(s,999,fp); if(strlen(s)>3){ for(i=0;i printf(\"%s\ } } if(fclose(fp)){ printf(\"can not close file!\\n\"); exit(0); } return 0; } 6.删除文件中的注释: 将C语言源程序(hello.c) 文件中的所有注释去掉后存入另一个文件(new_hello.c)。试编写相应程序。 解答: #include #include int main(void) { FILE *fp1,*fp2; char ch,ch1,ch2,s[99]; if((fp1=fopen(\"hello.c\ printf(\"can not open file!\\n\"); exit(0); } if((fp2=fopen(\"new_hello.c\ printf(\"can not open file!\\n\"); exit(0); } while(!feof(fp1)){ ch=fgetc(fp1); if(ch=='/'){ if((ch1=fgetc(fp1))=='*') while(fgetc(fp1)!='*'&&(ch1=fgetc(fp1))!='/') fseek(fp1,-sizeof(ch1),1); else if(ch1=='/'){ ch='\\0'; for(;ch1!='\\n';ch1=fgetc(fp1)) ch1='\\0'; } } else if(ch!=EOF) fputc(ch,fp2); } if(fclose(fp2)){ printf(\"can not close file!\\n\"); exit(0); } return 0; } 7.(选做) 账户余额管理: 创建一个随机文件,用来存储银行账户和余额信息,程序要求能够查询某个账户的余额,当客户发生交易额时(正表示存入,负表示取出)能够更新余额。账户信息包括账号、账号名和余额三个数据项。试编写相应程序。 文件部分内容如下: AcctNo AcctName Balance 1 zhangsan 1 000.00 2 lisi 1 300.00 3 wangwu -100.00 …… 解答: #include #include #include long size; struct account{ char no[10]; char acctname[50]; double balance; }; FILE *openfile(char *openmode){ FILE *fp; if((fp=fopen(\"accout.dat\ printf(\"Can not open the file!\"); exit(0); } return fp; } double userbalance(FILE *fp,char *name); void pay(FILE *fp,char *name,double count); int main() { FILE *fp; int choice; char name[50]; double balance; double count; printf(\"请输入选择类型:\\n\"); printf(\"1.查账户余额\\n\"); printf(\"2.账户交易\\n\"); printf(\"退出按exit\\n\"); printf(\"选择类型:\"); scanf(\"%d\ switch(choice){ case 1: printf(\"输入名字\"); scanf(\"%s\ fp=openfile(\"r+\"); balance=userbalance(fp,name); printf(\"%.2f\ break; case 2: printf(\"输入名字\"); scanf(\"%s\ fp=openfile(\"r+\"); printf(\"输入交易金额\"); scanf(\"%lf\ pay(fp,name,count); break; } default: exit(0); break; } return 0; } double userbalance(FILE *fp,char *name){ struct account user; double balance; rewind(fp); while(!feof(fp)){ fscanf(fp,\"%s %s %lf\ if(strcmp(user.acctname,name)==0){ balance=user.balance; break; } } return balance; } void pay(FILE *fp,char *name,double count){ FILE *fpout; struct account user; double balance; balance=userbalance(fp,name); balance=balance+count; rewind(fp); fpout=fopen(\"temp.dat\ while(!feof(fp)){ fscanf(fp,\"%s %s %lf\ if(strcmp(user.acctname,name)==0){ user.balance=balance; fprintf(fpout,\"%s %s %lf\\n\ } else fprintf(fpout,\"%s %s %lf\\n\ } if(fclose(fp)){ printf(\"can not close file!\\n\"); exit(0); } if(fclose(fpout)){ printf(\"can not close file!\\n\"); exit(0); } unlink(\"accout.dat\");//remove(\"accout.dat\");都是删除文件的函数 rename(\"temp.dat\ } 因篇幅问题不能全部显示,请点此查看更多更全内容