《C语言程序设计》第4版 何钦铭、颜晖主编 课后习题答案 第12章 课后习题

P304

练习12-1

文件缓冲区:内存中用于数据存储的数据块,在文件处理过程中,程序需要访问该缓冲区实现数据的存取。

在C程序中,文件类型指针主要的功能是:指向文件的缓冲区,通过移动指针实现对文件的操作。

P306

练习12-2

#include<stdio.h> //练习12-2 
#include<stdlib.h>
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<stdio.h>//练习12-3 
#include<stdlib.h>
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<stdio.h>//练习12-4 
#include<stdlib.h>
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<stdio.h>//练习12-5 
#include<stdlib.h>
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<stdio.h>//练习12-6 实数取整写入文件 
#include<stdlib.h>
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<logcount;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<logcount;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;
}

 

 

 

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值