P304
练习12-1
文件缓冲区:内存中用于数据存储的数据块,在文件处理过程中,程序需要访问该缓冲区实现数据的存取。
在C程序中,文件类型指针主要的功能是:指向文件的缓冲区,通过移动指针实现对文件的操作。
P306
练习12-2
#include//练习12-2 #include main() { int i,offset; char pw[80]; FILE *fp; if((fp=fopen("凯撒密码.txt","w"))==NULL){ printf("文件打开失败!"); exit(0); } printf("输入一个正整数offset:"); scanf("%d",&offset); getchar();//接受空格 printf("请输入一个字符串:"); gets(pw); for(i=0;pw[i]!=' ';i++)//循环取出 { if(pw[i]>='A'&&pw[i]<='Z'){//经检验,程序没有问题,可能是编译器的问题,字母B和b无法输出。(即输入Z 应输出B,无法正常显示)。 if((pw[i]+offset)<'Z'){//未超过最大的字母 pw[i]+=offset; }else pw[i]=pw[i]-('Z'-offset);//越界,倒着减 }else if(pw[i]>='a'&&pw[i]<='z'){ if((pw[i]+offset)<'z'){ pw[i]=pw[i]+offset; }else pw[i]=pw[i]-('z'-offset); }else pw[i]=pw[i]; } fprintf(fp,"%s",pw); fclose(fp); }
P311
第一问:判断文件是否结束,EOF是文件结束符。
#include//练习12-3 #include int main(void) { FILE *fp1,*fp2; int count=0; char ch,ch1; if((fp1=fopen("f12-2.txt","r"))==NULL){ printf("文件f12-2打开失败!"); exit(0); } if((fp2=fopen("f12-3.txt","w"))==NULL){ printf("文件f12-3打开失败!"); exit(0); } while(!feof(fp1)){ ch=fgetc(fp1); if(ch!=EOF){ fputc(ch,fp2); } } fclose(fp1); fclose(fp2); if((fp2=fopen("f12-3.txt","r"))==NULL){ printf("文件f12-3打开失败!"); exit(0); } while(!feof(fp2)){ ch1=fgetc(fp2); if(ch1!=EOF){ if(ch1!=' ')//包括了回车,有5个 count++; } } printf("f12-3中的字符数量为:%d",count); fclose(fp2); return 0; }
P317
练习12-4到12-6
#include//练习12-4 #include int main(void) { FILE *fp; char ch; int count=1; if((fp=fopen("letter.txt","r"))==NULL){ printf("文件打开失败!"); exit(0); } while(!feof(fp)){ ch=fgetc(fp); if(ch!=EOF){ if(ch>='A'&&ch<='Z'){ ch=ch+32; } if(ch=='n') count++; } printf("%c",ch); } printf("n共%d行",count); return 0; }
#include//练习12-5 #include int main(void) { FILE *fp; char ch,ch1; if((fp=fopen("f3.txt","w+"))==NULL){ printf("文件打开失败!"); exit(0); } printf("请输入一行字符:"); while((ch=getchar())!='n'){ fprintf(fp,"%c",ch); } rewind(fp); while(!feof(fp)){ ch=fgetc(fp); //用fscanf会将最后一个字符重复输出两遍 if(ch!=EOF) printf("%c",ch); } fclose(fp); return 0; }
#include//练习12-6 实数取整写入文件 #include void splitfloat(double x,int *intpart,double *fracpart) { *intpart=(int)x;//强制转换为整型 *fracpart=x-*intpart;//直接减去整数部分可得小数部分 } int main(void) { FILE *fp1,*fp2; int intpart;//x=345.89,小数部分为0.890015 double z,fracpart,a;//x=123.456,小数部分会输出为0.456001 if((fp1=fopen("f1.txt","r"))==NULL){ printf("文件f1打开失败!"); exit(0); } if((fp2=fopen("f2.txt","w"))==NULL){ printf("文件f2打开失败!"); exit(0); } while(!feof(fp1)){ fscanf(fp1,"%lf",&z);//读取 if(z!=EOF){ splitfloat(z,&intpart,&fracpart);//拆分整数和小数部分 // printf("整数部分:%dn小数部分:%lfn",intpart,fracpart);//帮助检验 if(fracpart>=0.5){//小数部分 四舍五入 intpart=intpart+1; // printf("整数部分:%dn小数部分:%lfn",intpart,fracpart);//帮助检验 } fprintf(fp2,"%dn",intpart); } } return 0; }
P321
练习12-7
#include"stdio.h"//练习12-7
#include"stdlib.h"
#include"process.h"
#include"string.h"
long size;
struct LogData{
long logid;
char logdate[11];
char lognote[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.n4-Update a LOGn0-End program.n");
scanf("%d",&mychoice);
return mychoice;
}
long getLogcount(FILE *cfptr)
{
long begin,end,logcount;
fseek(cfptr,0L,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,0L,SEEK_SET);
fread(&log,size,1,cfptr);
printf("logidtlogdata tlognote tchargettbalancen");
while(!feof(cfptr)){
printf("%ldt%st%st%.2lftt%.2lfn",log.logid,log.logdate,log.lognote,log.charge,log.balance);
fread(&log,size,1,cfptr);
}
}
int QueryLastLog(FILE *cfptr)
{
struct LogData log;
long logcount;
int flag=0;
logcount=getLogcount(cfptr);
if(logcount>0)
{
fseek(cfptr,size*(logcount-1),SEEK_SET);
fread(&log,size,1,cfptr);
flag=1;
printf("The last log is:n");
printf("logid:%-6ldnlogdate:%-11snlognote:%-15sn",log.logid,log.logdate,log.lognote);
printf("charge:%-10.2lfnbalance:%-10.2lfn",log.charge,log.balance);
}
else printf("no logs is file!n");
return flag;
}
void AddNewLog(FILE *cfptr)
{
struct LogData log,lastlog;
long logcount;
printf("Input logdate(format:2006-01-01):");
scanf("%s",log.logdate);
printf("Input lognote:");
scanf("%s",log.lognote);
printf("Input Charge:Income+and expend-:");
scanf("%lf",&log.charge);
logcount=getLogcount(cfptr);
if(logcount>0){
fseek(cfptr,size*(logcount-1),SEEK_SET);
fread(&lastlog,size,1,cfptr);
log.logid=lastlog.logid+1;//记录号按顺序是上次的号+1
log.balance=log.charge+lastlog.balance ;
}
else {
log.logid=1;
log.balance=log.charge;
}
rewind(cfptr);
printf("logid=%ldn",log.logid);
fwrite(&log,sizeof(struct LogData),1,cfptr);
}
void UpdateLog(FILE *cfptr)//修改 ,先查询再修改
{
FILE *fp;
struct LogData log[1000],newlog,*plog=log;
long id,logcount,i,index=-1;
char ch;
printf("请输入一个记录ID:");
scanf("%ld",&id);
logcount=getLogcount(cfptr); //获取记录数
rewind(cfptr);
fread(plog,size,logcount,cfptr);
for(i=0;i=0){//没有找到
printf("Input logdate(format:2020-01-01):");
scanf("%s",newlog.logdate);
printf("Input lognote:");
scanf("%s",newlog.lognote);
printf("Input Charge:Income+ and expend-:");
scanf("%lf",&newlog.charge);
if(strcmp(log[index].lognote,newlog.lognote)!=0)//比较,如果不相同,则修改
strcpy(log[index].lognote,newlog.lognote);
if(strcmp(log[index].logdate,newlog.logdate)!=0)
strcpy(log[index].logdate,newlog.logdate);
if(newlog.charge!=log[index].charge){//如果输入的收支额度改变,重新计算余额
newlog.balance=log[index].balance-log[index].charge+newlog.charge;
log[index].charge=newlog.charge;
log[index].balance=newlog.balance;
for(i=index+1;i



