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


    P304

    练习12-1

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

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

    P306

    练习12-2

    1. #include //练习12-2
    2. #include
    3. main()
    4. {
    5. int i,offset;
    6. char pw[80];
    7. FILE *fp;
    8. if((fp=fopen("凯撒密码.txt","w"))==NULL){
    9. printf("文件打开失败!");
    10. exit(0);
    11. }
    12. printf("输入一个正整数offset:");
    13. scanf("%d",&offset);
    14. getchar();//接受空格
    15. printf("请输入一个字符串:");
    16. gets(pw);
    17. for(i=0;pw[i]!='\0';i++)//循环取出
    18. {
    19. if(pw[i]>='A'&&pw[i]<='Z'){//经检验,程序没有问题,可能是编译器的问题,字母B和b无法输出。(即输入Z 应输出B,无法正常显示)。
    20. if((pw[i]+offset)<'Z'){//未超过最大的字母
    21. pw[i]+=offset;
    22. }else pw[i]=pw[i]-('Z'-offset);//越界,倒着减
    23. }else if(pw[i]>='a'&&pw[i]<='z'){
    24. if((pw[i]+offset)<'z'){
    25. pw[i]=pw[i]+offset;
    26. }else pw[i]=pw[i]-('z'-offset);
    27. }else pw[i]=pw[i];
    28. }
    29. fprintf(fp,"%s",pw);
    30. fclose(fp);
    31. }

    P311

    第一问:判断文件是否结束,EOF是文件结束符。

    1. #include//练习12-3
    2. #include
    3. int main(void)
    4. {
    5. FILE *fp1,*fp2;
    6. int count=0;
    7. char ch,ch1;
    8. if((fp1=fopen("f12-2.txt","r"))==NULL){
    9. printf("文件f12-2打开失败!");
    10. exit(0);
    11. }
    12. if((fp2=fopen("f12-3.txt","w"))==NULL){
    13. printf("文件f12-3打开失败!");
    14. exit(0);
    15. }
    16. while(!feof(fp1)){
    17. ch=fgetc(fp1);
    18. if(ch!=EOF){
    19. fputc(ch,fp2);
    20. }
    21. }
    22. fclose(fp1);
    23. fclose(fp2);
    24. if((fp2=fopen("f12-3.txt","r"))==NULL){
    25. printf("文件f12-3打开失败!");
    26. exit(0);
    27. }
    28. while(!feof(fp2)){
    29. ch1=fgetc(fp2);
    30. if(ch1!=EOF){
    31. if(ch1!=' ')//包括了回车,有5个
    32. count++;
    33. }
    34. }
    35. printf("f12-3中的字符数量为:%d",count);
    36. fclose(fp2);
    37. return 0;
    38. }

    P317 

    练习12-4到12-6

    1. #include//练习12-4
    2. #include
    3. int main(void)
    4. {
    5. FILE *fp;
    6. char ch;
    7. int count=1;
    8. if((fp=fopen("letter.txt","r"))==NULL){
    9. printf("文件打开失败!");
    10. exit(0);
    11. }
    12. while(!feof(fp)){
    13. ch=fgetc(fp);
    14. if(ch!=EOF){
    15. if(ch>='A'&&ch<='Z'){
    16. ch=ch+32;
    17. }
    18. if(ch=='\n') count++;
    19. }
    20. printf("%c",ch);
    21. }
    22. printf("\n共%d行",count);
    23. return 0;
    24. }
    1. #include//练习12-5
    2. #include
    3. int main(void)
    4. {
    5. FILE *fp;
    6. char ch,ch1;
    7. if((fp=fopen("f3.txt","w+"))==NULL){
    8. printf("文件打开失败!");
    9. exit(0);
    10. }
    11. printf("请输入一行字符:");
    12. while((ch=getchar())!='\n'){
    13. fprintf(fp,"%c",ch);
    14. }
    15. rewind(fp);
    16. while(!feof(fp)){
    17. ch=fgetc(fp); //用fscanf会将最后一个字符重复输出两遍
    18. if(ch!=EOF) printf("%c",ch);
    19. }
    20. fclose(fp);
    21. return 0;
    22. }

     

    1. #include//练习12-6 实数取整写入文件
    2. #include
    3. void splitfloat(double x,int *intpart,double *fracpart)
    4. {
    5. *intpart=(int)x;//强制转换为整型
    6. *fracpart=x-*intpart;//直接减去整数部分可得小数部分
    7. }
    8. int main(void)
    9. {
    10. FILE *fp1,*fp2;
    11. int intpart;//x=345.89,小数部分为0.890015
    12. double z,fracpart,a;//x=123.456,小数部分会输出为0.456001
    13. if((fp1=fopen("f1.txt","r"))==NULL){
    14. printf("文件f1打开失败!");
    15. exit(0);
    16. }
    17. if((fp2=fopen("f2.txt","w"))==NULL){
    18. printf("文件f2打开失败!");
    19. exit(0);
    20. }
    21. while(!feof(fp1)){
    22. fscanf(fp1,"%lf",&z);//读取
    23. if(z!=EOF){
    24. splitfloat(z,&intpart,&fracpart);//拆分整数和小数部分
    25. // printf("整数部分:%d\n小数部分:%lf\n",intpart,fracpart);//帮助检验
    26. if(fracpart>=0.5){//小数部分 四舍五入
    27. intpart=intpart+1;
    28. // printf("整数部分:%d\n小数部分:%lf\n",intpart,fracpart);//帮助检验
    29. }
    30. fprintf(fp2,"%d\n",intpart);
    31. }
    32. }
    33. return 0;
    34. }

    P321

    练习12-7

    1. #include"stdio.h"//练习12-7
    2. #include"stdlib.h"
    3. #include"process.h"
    4. #include"string.h"
    5. long size;
    6. struct LogData{
    7. long logid;
    8. char logdate[11];
    9. char lognote[15];
    10. double charge;
    11. double balance;
    12. };
    13. int inputchoice()
    14. {
    15. int mychoice;
    16. printf("\nEnter your choice:\n");
    17. printf("1-Add a new cash LOG.\n2-List All Cash LOG.\n");
    18. printf("3-Query Last Cash LOG.\n4-Update a LOG\n0-End program.\n");
    19. scanf("%d",&mychoice);
    20. return mychoice;
    21. }
    22. long getLogcount(FILE *cfptr)
    23. {
    24. long begin,end,logcount;
    25. fseek(cfptr,0L,SEEK_SET);
    26. begin=ftell(cfptr);
    27. fseek(cfptr,size,SEEK_END);
    28. end=ftell(cfptr);
    29. logcount=(end-begin)/size-1;
    30. return logcount;
    31. }
    32. void ListAllLog(FILE *cfptr)
    33. {
    34. struct LogData log;
    35. fseek(cfptr,0L,SEEK_SET);
    36. fread(&log,size,1,cfptr);
    37. printf("logid\tlogdata \tlognote \tcharge\t\tbalance\n");
    38. while(!feof(cfptr)){
    39. printf("%ld\t%s\t%s\t%.2lf\t\t%.2lf\n",log.logid,log.logdate,log.lognote,log.charge,log.balance);
    40. fread(&log,size,1,cfptr);
    41. }
    42. }
    43. int QueryLastLog(FILE *cfptr)
    44. {
    45. struct LogData log;
    46. long logcount;
    47. int flag=0;
    48. logcount=getLogcount(cfptr);
    49. if(logcount>0)
    50. {
    51. fseek(cfptr,size*(logcount-1),SEEK_SET);
    52. fread(&log,size,1,cfptr);
    53. flag=1;
    54. printf("The last log is:\n");
    55. printf("logid:%-6ld\nlogdate:%-11s\nlognote:%-15s\n",log.logid,log.logdate,log.lognote);
    56. printf("charge:%-10.2lf\nbalance:%-10.2lf\n",log.charge,log.balance);
    57. }
    58. else printf("no logs is file!\n");
    59. return flag;
    60. }
    61. void AddNewLog(FILE *cfptr)
    62. {
    63. struct LogData log,lastlog;
    64. long logcount;
    65. printf("Input logdate(format:2006-01-01):");
    66. scanf("%s",log.logdate);
    67. printf("Input lognote:");
    68. scanf("%s",log.lognote);
    69. printf("Input Charge:Income+and expend-:");
    70. scanf("%lf",&log.charge);
    71. logcount=getLogcount(cfptr);
    72. if(logcount>0){
    73. fseek(cfptr,size*(logcount-1),SEEK_SET);
    74. fread(&lastlog,size,1,cfptr);
    75. log.logid=lastlog.logid+1;//记录号按顺序是上次的号+1
    76. log.balance=log.charge+lastlog.balance ;
    77. }
    78. else {
    79. log.logid=1;
    80. log.balance=log.charge;
    81. }
    82. rewind(cfptr);
    83. printf("logid=%ld\n",log.logid);
    84. fwrite(&log,sizeof(struct LogData),1,cfptr);
    85. }
    86. void UpdateLog(FILE *cfptr)//修改 ,先查询再修改
    87. {
    88. FILE *fp;
    89. struct LogData log[1000],newlog,*plog=log;
    90. long id,logcount,i,index=-1;
    91. char ch;
    92. printf("请输入一个记录ID:");
    93. scanf("%ld",&id);
    94. logcount=getLogcount(cfptr); //获取记录数
    95. rewind(cfptr);
    96. fread(plog,size,logcount,cfptr);
    97. for(i=0;i
    98. if(id==log[i].logid){ //找到
    99. printf("logid\tlogdata \tlognote \tcharge\t\tbalance\n");//显示当前记录
    100. printf("%ld\t%s\t%s\t%.2lf\t\t%.2lf\n",
    101. log[i].logid,log[i].logdate,log[i].lognote,log[i].charge,log[i].balance);
    102. index=i;
    103. break;
    104. }
    105. }
    106. rewind(cfptr); //有或者没有都无影响
    107. if(index>=0){//没有找到
    108. printf("Input logdate(format:2020-01-01):");
    109. scanf("%s",newlog.logdate);
    110. printf("Input lognote:");
    111. scanf("%s",newlog.lognote);
    112. printf("Input Charge:Income+ and expend-:");
    113. scanf("%lf",&newlog.charge);
    114. if(strcmp(log[index].lognote,newlog.lognote)!=0)//比较,如果不相同,则修改
    115. strcpy(log[index].lognote,newlog.lognote);
    116. if(strcmp(log[index].logdate,newlog.logdate)!=0)
    117. strcpy(log[index].logdate,newlog.logdate);
    118. if(newlog.charge!=log[index].charge){//如果输入的收支额度改变,重新计算余额
    119. newlog.balance=log[index].balance-log[index].charge+newlog.charge;
    120. log[index].charge=newlog.charge;
    121. log[index].balance=newlog.balance;
    122. for(i=index+1;i//当前记录之后的每条记录余额信息更新
    123. log[i].balance=log[i-1].balance+log[i].charge;
    124. }
    125. rewind(cfptr);
    126. fwrite(plog,size,logcount,cfptr); //更新回文件,此处用只读的方式打开
    127. }
    128. else{
    129. printf("Error logid and try another!\n");
    130. }
    131. }
    132. int main(void)
    133. {
    134. FILE *fp;
    135. int choice;
    136. if((fp=fopen("cashbox.dat","ab+"))==NULL){//以此方式打开,写入的数据会被添加到原有数据的后面。所以更新要重新用rb+的方式打开
    137. printf("can not open file cashbox.dat!\n");
    138. exit(0);
    139. }
    140. size=sizeof(struct LogData);
    141. while((choice=inputchoice())!=0){
    142. switch(choice){
    143. case 1:AddNewLog(fp);break;
    144. case 2:ListAllLog(fp);break;
    145. case 3:QueryLastLog(fp);break;
    146. case 4:fp=fopen("cashbox.dat", "rb+");UpdateLog(fp);break;//增加文件打卡方式为只读,则只更新不添加
    147. default:printf("Input Error.");break;
    148. }
    149. }
    150. fclose(fp);
    151. return 0;
    152. }

     

     

     

  • 相关阅读:
    MySQL-内置函数
    左右切换箭头代替滚动条,实现类似走马灯效果
    Kitex源码阅读——脚手架代码是如何通过命令行生成的(二)
    软件开发项目文档系列之十如何撰写测试用例
    一名技术主管应该是创作者
    讲讲存档文件的包装设计
    R语言使用plot函数可视化数据散点图,通过xlim参数指定X轴的坐标范围(x axis limits)
    网络工程师的背包(EDC总结推荐)
    拉美巴西阿根廷媒体宣发稿墨西哥哥伦比亚新闻营销如何助推跨境出海推广?
    UE4和C++ 开发-C++绑定widget的方式和初始化UI
  • 原文地址:https://blog.csdn.net/CSDNChinaLUCKY/article/details/126150145