博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C Primer Plus 第13章 文件输入/输出 13.11 编程练习答案
阅读量:5975 次
发布时间:2019-06-19

本文共 14191 字,大约阅读时间需要 47 分钟。

hot3.png

1.修改程序清单13.1中的程序,使之不采用命令行参数,而是请求用户输入文件名并读入用户的响应。

(程序清单13.1示范了如何使用标准I/O读取文件和统计文件中的字符个数)

#include
#include
//ANSIC 的exit()原型int main(void){ int ch; FILE *fp; long count = 0; char name[41]; printf("Input the file's name: "); scanf("%s",name); if((fp=fopen(name,"r"))==NULL) { printf ("Can't open %s\n", name); exit(1); } while((ch=getc(fp))!=EOF) { putc(ch,stdout); count++; } fclose(fp); printf("\nFile %s has %ld characters\n",name,count); return 0;}

2、编写一个文件复制程序。程序需要从命令行获得源文件名和目的文件名尽可能使用标准I/O和二进制模式。

#include
#include
int main(int argc,char *argv[]){ int ch; FILE *source,*destination; if((source=fopen(argv[1],"rb"))==NULL) { printf ("Can't open %s\n", argv[1]); exit(1); } if((destination=fopen(argv[2],"wb"))==NULL) { printf ("Can't open %s\n", argv[2]); exit(1); } while((ch=getc(source))!=EOF) putc(ch,destination); fclose(source); fclose(destination); printf("copy finished\n"); return 0;}

  3.编写一个文件复制程序,提示用户输名入源文件名和输出文件。在向输出文件写入时,程序应当使用ctype.h中定义的toupper()函数将所有的文本转换成大写。使用标准I/O和文本模式。

#include
#include
#include
int main(void){ int ch; FILE *source,*destination; char source_name[41],destination_name[41]; printf("Input the source file's name:"); if((source=fopen(gets(source_name),"r"))==NULL) { printf("Can't open %s\n", source_name); exit(1); } printf("Input the destination file's name:"); if((destination=fopen(gets(destination_name),"w"))==NULL) { printf("Can't open %s\n", destination_name); exit(1); } while((ch=getc(source))!=EOF) putc(toupper(ch),destination); fclose(source); fclose(destination); printf("Copy finished!\n"); return 0;}

4、编写一段程序,依次在屏幕上显示命令行中列出的全部文件。使用argc控制循环

#include
#include
int main(int argc,char *argv[]){ int i,n=argc; char str[100]; FILE *fp; for(i=1;i<4;i++) { printf("\nFILE %d -- %s:\n",i,argv[i]); if((fp=fopen(argv[i],"r"))==NULL) { printf("Can't open %s\n",argv[i]); exit(1); } while(fscanf(fp,"%s",str)!=EOF) fprintf(stdout,"%s",str); fclose(fp); } return 0;}

5.修改程序清单13.6中的程序,使用命令行参数(而不是交互式界面)获得文件名。

(把多个文件的内容追加到一个文件)

#include
#include
#include
#define BUFSIZE 1024#define SLEN 81void append(FILE *source, FILE *dest);int main(int argc,char *argv[]){ FILE *fa,*fs; //fa for append file, fs for source file int file=0;i; // number of files appended if((fa=fopen(argv[1],"a"))==NULL) { fprintf(stderr,"Can't open %s\n", argv[1]); exit(2); } if(setvbuf(fa,NULL,_IOFBF,BUFSIZE)!=0) { fputs("Can't create output buffer\n",stderr); exit(3); } for(i=2;i
0) fwrite(temp,sizeof(char),bytes,dest); }

6.使用命令行参数的程序要求用户记住正确的使用方法。重写程序清单13.2中的程序,不使用命令行参数,而是提示用户键入所需的信息。

#include
#include
//for exit()#include
//for strcopy(),strcat()#define LEN 40int main(void){ FILE *in, *out; //declare two FILE pointers int ch; char name[LEN]; //storage for output filename int count = 0; //set up input puts("Enter the name of the file to be reduce"); gets(name); if((in=fopen(name,"r"))==NULL) { fprintf(stderr,"I could't open the file \"%s\"\n",name); exit(2); } //set up output name[LEN-5]='\0'; strcat(name,".red"); //append.red if((out=fopen(name,"w"))==NULL) { fprintf(stderr,"Can't create output file.\n"); exit(3); } //copy date while((ch=getc(in))!=EOF) if(count++ % 3 == 0) putc(ch,out); //print every 3rd char //clean up if(fclose(in)!=0 or fclose(out)!=0) fprintf(stderr,"Error in closing files\n"); return 0;}

    7.编写一个打开两个文件的程序。可以使用命令行参数或者请求用户输入来获得文件名。

    a.让程序打印第一个文件的第一行、第二个文件的第一行、第一个文件的第二行、第二个文件的第二行,依此类推,直到打印完行数较多的文件的最后一行。

#include
#include
#define M 100int main(int argc,char *argv[]){ FILE *fp1,*fp2; char str1[M],str2[M]; int E1,E2; if((fp1=fopen(argv[1],"r"))==NULL) { printf("Can't open %s",argv[1]); exit(1); } if((fp2=fopen(argv[2],"r"))==NULL) { printf("Can't open %s",argv[2]); exit(1); } while(1) { if((E1=fscanf(fp1,"%s",str1))==1) puts(str1); if((E2=fscanf(fp2,"%s",str2))==1) puts(str2); if(E1!=1 && E2!=1) break; } fclose(fp1); fclose(fp2); return 0;}

 b.修改程序,把行号相同的行打印到同一行上。(输出由Puts( )换成printf( ))

#include
#include
#define M 100int main(int argc,char *argv[]){ FILE *fp1,*fp2; char str1[M],str2[M]; int E1,E2; if((fp1=fopen(argv[1],"r"))==NULL) { printf("Can't open %s",argv[1]); exit(1); } if((fp2=fopen(argv[2],"r"))==NULL) { printf("Can't open %s",argv[2]); exit(1); } while(1) { if((E1=fscanf(fp1,"%s",str1))==1) printf("%s",str1); if((E2=fscanf(fp2,"%s",str2))==1) printf("%s",str2); if(E1!=1 && E2!=1) break; printf("\n"); } fclose(fp1); fclose(fp2); return 0;}

    8.编写一段程序,将一个字符、零个或多个文件名作为命令行参数。如果字符后没有参数跟随,程序读取标准输入文件。否则,程序依次打开每个文件,然后报告每个文件中该字符的出现次数。文件名和字符本身也与计数值一起报告。程序中包括错误检查,以确定参数数目是否正确和是否能打开文件。如果不能打开文件,程序要报告这一情况然后继续处理下一文件。

#include
#include
int count(char ch,FILE *fp);int main(int argc,char *argv[]){ int i; char ch; FILE *fp; if(argc<2) { printf("no char?\n"); exit(1); } ch=argv[1][0]; if(argc==2) { printf("Input a article:"); printf("In your input: %c has been appeared %d times.\n",ch,count(ch,stdin)); } else for(i=2;i

  9.修改程序清单13.3中的程序,从l开始,根据加入列表的顺序为每个单词编号。当再次运行程序时,确保新的单词编号接着前面的编号开始。

#include
#include
#define MAX 40int main(void){ FILE *fp; char words[MAX]; int count = 0; if((fp=fopen("wordy","a+"))==NULL) { fprintf(stdout,"Can't open \"wordy\" file.\n"); exit(1); } rewind(fp); while(fgets(words,MAX-1,fp)!=NULL) count++; puts("Enter words to add to the file;press the enter"); puts("key at the beginning of a line to terminate."); while(gets(words)!=NULL && words[0]!='\0') fprintf(fp,"%d:%s\n",count++,words); puts("File counts:"); rewind(fp); while(fscanf(fp,"%s",words)==1) puts(words); if(fclose(fp)!=0) fprintf(stderr,"Error closing file\n"); return 0;}

    10.编写一个程序,打开一个文本文件,文件名通过交互方式获得。建立一个循环,请求用户输入一个文件位置。然后程序打印文件中从该位置开始到下一换行符之间的部分。用户通过输入非数字字符来终止输入循环。

#include
#include
#define MAX 81int main(void){ char name[30],content[MAX]; int row,column; FILE *fp; printf("Input the name of file:"); gets(name); if((fp=fopen(name,"r"))==NULL) { printf("Can't open %s",name); exit(1); } printf("Input the row and column to output:"); while(scanf("%d%d",&row,&column)==2) { row--,column--; fseek(fp,0,SEEK_SET); while(row--) fgets(content,MAX,fp); fseek(fp,column,SEEK_CUR); fgets(content,MAX,fp); printf(content); printf("Input the start position to output:"); } printf("Quit\n"); return 0;}

    11.编写一个程序,接受两个命令行参数。第一个参数为一个字符串;第二个为文件名。程序打印文件中包含该字符串的所有行。因为这一任务是面向行而不是面向字符的,所以要使用fgets()而不是getc()。使用标准C库函数strstr()(在第II章的练习7中简要描述过)在每一行中搜索这一字符串。

#include
#include
#include
#define MAX 201int main(int argc,char *argv[]){ FILE *fp; char str[MAX]; if((fp=fopen(argv[2],"r"))==NULL) { printf("Can't open %s",argv[2]); exit(1); } while(fgets(str,MAX,fp)!=NULL) if(strstr(str,argv[1])!=NULL) printf(str); return 0;}

 12.创建一个包含20行,每行30个整数的文本文件。整数在O到9之间,用空格分开。该文件是一个图片的数字表示,从0到9的值代表逐渐增加的灰度。编写一个程序,将文件的内容读入到一个20*30的int数组中。一种将这种数字表示转化成图片的粗略方法就是让程序使用数组中的数值来初始化一个20*31的字符阵列。0对应空格字符,l对应句号字符,依此类推,较大的值对应占用空间较多的字符。比如,可以使用#代表9。每行的最后一个字符(第31个)为空字符,这样数组将包含20个字符串。然后程序显示结果图片(即打印这些字符串),并将结果存入一个文本文件中。例如,如果开始的数据为:

0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 2 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 5 2 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 5 8 1 9 8 5 4 5 2 0 0 0 0 0 0 0 0 0

0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 0 4 5 2 0 0 0 0 0 0 0 0

0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 4 5 2 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 1 8 5 0 0 0 4 5 2 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 4 5 2 0 0 0 0 0

5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5

8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8

9 9 9 9 0 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 3 9 9 9 9 9 9 9

8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8

5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5

0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0

0 0 0 0 2 2 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0

0 0 0 0 3 3 0 0 0 0 0 0 5 8 9 9 8 5 0 5 6 1 1 1 1 6 5 0 0 0

0 0 0 0 4 4 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0

0 0 0 0 5 5 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0

 

对于一种特定的输出字符的选择,输出是这样的:

 

  #         *%##%*'

    #       *%##%**'

            *%.#%*~*'

    #       *%##%* ~*'

  #         *%##%*  ~*'

            *%#.%*   ~*'

            *%##%*    ~*'

*************%##%*************

%%%%%%%%%%%%*%##%*%%%%%%%%%%%%

#### #################:#######

%%%%%%%%%%%%*%##%*%%%%%%%%%%%%

*************%##%*************

            *%##%*

            *%##%*    ==

    ''      *%##%*  *=  =*

    ::      *%##%* *=....=*

    ~~      *%##%*  *=  =*

    **      *%##%*    ==

            *%##%*

            *%##%*

#include
#include
int main(void){ FILE *fp; char name[30],photo[20][31],table[]=" .':~*=&%@"; int num[20][30],row,column,i=0; printf("Input the name of source file:"); gets(name); if((fp=fopen(name,"r"))==NULL) { printf("Can't open %s",name); exit(1); } for(row=0;row<20;row++) for(column=0;column<30;column++) fscanf(fp,"%d",&num[row][column]); for(row=0;row<20;row++) { for(column=0;column<30;column++) photo[row][column]=table[num[row][column]]; photo[row][column]='\0'; } for(row=0;row<20;row++) puts(photo[row]); printf("Input the name of destination file:"); gets(name); if((fp=fopen(name,"w"))==NULL) { printf("Can't open %s",name); exit(1); } for(row=0;row<20;row++) fprintf(fp,"%s\n",photo[row]); return 0;}

    13.数字图像,尤其是从宇宙飞船发回的数字图像可能会包含尖峰脉冲。为第12道编程练习题添加消除尖峰脉冲的函数。该函数应该将每一个值和它上下左右的相邻值比较,如果该值与它周围每个值的差都大于1,就用所有相邻值的平均值(取与其最接近的整数)取代这个值。注意到边界上的点的相邻点少于4个,所以它们需要特殊处理。

#include 
#include
int main(void){ FILE *fp; char name[30],photo[20][31],table[] = " .':~*=&%@"; int num[20][30],row,column,i=0; printf("input the name of source file:"); gets(name); if ( ( fp=fopen(name,"r") ) == NULL ) { printf("Can't open %s",name); exit(1); } for (row=0; row<20; row++) for (column=0; column<30; column++) fscanf(fp,"%d",&num[row][column]); for (row=0; row<20; row++) for (column=0; column<30; column++) { if(row==0&&column==0) //处理第1行第1个数 { if( (num[row][column] - num[row][column+1])>1 && (num[row][column] - num[row+1][column])>1 ) num[row][column] = ( num[row][column+1] + num[row+1][column] ) / 2 + 0.5;//加0.5是为了四舍五入 } else if(row==0&&column==29) //处理第1行最后1个数 { if( (num[row][column] - num[row][column-1])>1 && (num[row][column] - num[row+1][column])>1 ) num[row][column] = ( num[row][column-1] + num[row+1][column] ) / 2 + 0.5; } else if(row==19&&column==0) //处理最后1行第1个数 { if( (num[row][column] - num[row-1][column])>1 && (num[row][column] - num[row][column+1])>1 ) num[row][column] = ( num[row-1][column] + num[row][column+1] ) / 2 + 0.5; } else if(row==19&&column==29) //处理最后1行最后1个数 { if( (num[row][column] - num[row-1][column])>1 && (num[row][column] - num[row][column-1])>1 ) num[row][column] = ( num[row-1][column] + num[row][column-1] ) / 2 + 0.5; } else if(row==0) //处理第1行中间的数 { if( (num[row][column] - num[row][column-1])>1 && (num[row][column] - num[row+1][column])>1 && (num[row][column] - num[row][column+1])>1 ) num[row][column] = ( num[row][column-1] + num[row+1][column] + num[row][column+1]) / 3 + 0.5; } else if(column==0) //处理第1列中间的数 { if( (num[row][column] - num[row-1][column])>1 && (num[row][column] - num[row+1][column])>1 && (num[row][column] - num[row][column+1])>1 ) num[row][column] = ( num[row-1][column] + num[row+1][column] + num[row][column+1]) / 3 + 0.5; } else if(row==19) //处理最后1行中间的数 { if( (num[row][column] - num[row-1][column])>1 && (num[row][column] - num[row][column-1])>1 && (num[row][column] - num[row][column+1])>1 ) num[row][column] = ( num[row-1][column] + num[row][column-1] + num[row][column+1]) / 3 + 0.5; } else if(column==29) //处理最后1列中间的数 { if( (num[row][column] - num[row-1][column])>1 && (num[row][column] - num[row+1][column])>1 && (num[row][column] - num[row][column-1])>1 ) num[row][column] = ( num[row-1][column] + num[row+1][column] + num[row][column-1]) / 3 + 0.5; } else //处理中间的数 { if( (num[row][column] - num[row-1][column])>1 && (num[row][column] - num[row+1][column])>1 && (num[row][column] - num[row][column-1])>1 && (num[row][column] - num[row][column+1])>1 ) num[row][column] = ( num[row-1][column] + num[row+1][column] + num[row][column-1]) + num[row][column+1]/ 4 + 0.5; } } for (row=0; row<20; row++) //数字与图形转换 { for (column=0; column<30; column++) photo[row][column] = table[ num[row][column] ]; photo[row][column] = '\0'; } for (row=0; row<20; row++) puts(photo[row]); printf("input the name of destination file:"); gets(name); if ( ( fp=fopen(name,"w") ) == NULL ) { printf("Can't open %s",name); exit(1); } for (row=0; row<20; row++) fprintf(fp,"%s\n",photo[row]); return 0;}

 

转载于:https://my.oschina.net/idreamo/blog/855134

你可能感兴趣的文章
不得不懂系列(1)-Go语言protobuf快速上手
查看>>
版本控制系统git
查看>>
从月薪5k到5w的过来人 给大学生程序员们的一点建议
查看>>
Android开发之 .9PNG 的使用
查看>>
D2 日报 2019年5月8日
查看>>
武汉区块链软件技术公司:区块链和比特币
查看>>
学习笔记(3.27)
查看>>
ecshop ajax无刷新登陆_无需整理
查看>>
Android中隐藏标题栏和状态栏
查看>>
浅显c#连接数据库
查看>>
15. SQL -- 游标(实例)
查看>>
plsql9.0.6.1665版本注册码
查看>>
Linux入门基础之grep命令详解及正则表达式
查看>>
Git 分布式版本控制 实战
查看>>
Linux之Find命令详解
查看>>
crysis2 video&cryengine3 editor show
查看>>
数据挖掘 numpy之数组定义
查看>>
Hibernate学习之SessionFactory的opensession 和 getCu...
查看>>
web网站服务(二)
查看>>
【第一期】网站打开错误问题解决方法集合
查看>>