搜索
您的当前位置:首页正文

C语言知识学习程序设计(第3版)何钦铭颜晖第12章文件

2020-05-12 来源:易榕旅网
第12章 文件

【练习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(maxmax=students[i].score;

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;iif(pwd[i]=='z')

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;iif(s[i]=='f'&&s[i+1]=='o'&&s[i+2]=='r')

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\

}

因篇幅问题不能全部显示,请点此查看更多更全内容

Top