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]!='\0';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("整数部分:%d\n小数部分:%lf\n",intpart,fracpart);//帮助检验
- if(fracpart>=0.5){//小数部分 四舍五入
- intpart=intpart+1;
- // printf("整数部分:%d\n小数部分:%lf\n",intpart,fracpart);//帮助检验
- }
- fprintf(fp2,"%d\n",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 LOG\n0-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("logid\tlogdata \tlognote \tcharge\t\tbalance\n");
- while(!feof(cfptr)){
- printf("%ld\t%s\t%s\t%.2lf\t\t%.2lf\n",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:%-6ld\nlogdate:%-11s\nlognote:%-15s\n",log.logid,log.logdate,log.lognote);
- printf("charge:%-10.2lf\nbalance:%-10.2lf\n",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=%ld\n",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
- if(id==log[i].logid){ //找到
- printf("logid\tlogdata \tlognote \tcharge\t\tbalance\n");//显示当前记录
- printf("%ld\t%s\t%s\t%.2lf\t\t%.2lf\n",
- log[i].logid,log[i].logdate,log[i].lognote,log[i].charge,log[i].balance);
- index=i;
- break;
- }
- }
- rewind(cfptr); //有或者没有都无影响
- if(index>=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
//当前记录之后的每条记录余额信息更新 - log[i].balance=log[i-1].balance+log[i].charge;
- }
- rewind(cfptr);
- fwrite(plog,size,logcount,cfptr); //更新回文件,此处用只读的方式打开
- }
- else{
- printf("Error logid and try another!\n");
- }
- }
-
- int main(void)
- {
- FILE *fp;
- int choice;
-
- if((fp=fopen("cashbox.dat","ab+"))==NULL){//以此方式打开,写入的数据会被添加到原有数据的后面。所以更新要重新用rb+的方式打开
- printf("can not open file cashbox.dat!\n");
- exit(0);
- }
- size=sizeof(struct LogData);
- while((choice=inputchoice())!=0){
- switch(choice){
- case 1:AddNewLog(fp);break;
- case 2:ListAllLog(fp);break;
- case 3:QueryLastLog(fp);break;
- case 4:fp=fopen("cashbox.dat", "rb+");UpdateLog(fp);break;//增加文件打卡方式为只读,则只更新不添加
- default:printf("Input Error.");break;
- }
- }
- fclose(fp);
-
- return 0;
- }
-