《C Primer Plus(第五版)中文版》第13章第1至13题
2015-08-25 20:53
543 查看
/* * 1.修改程序清单13.1中的程序,使之不采用命令行参数,而是请求用户输入文件名并读入用户响应,。 */ #include <stdio.h> #include <stdlib.h> int main(void){ int ch; char inch[20] = {0}; long int count = 0; FILE * fp; printf("请输入你要统计的文件名称:\n"); scanf("%s",inch); fp = fopen(inch,"r"); if(fp == NULL) { puts("这个文件不存在."); exit(1); } while((ch=getc(fp)) !=EOF){ putc(ch,stdout); count++; } fclose(fp); printf("这个文件中%ld个字符",count); return 0; }
/* * 2.编写一个文件复制程序,程序需要从命令行获得源文件名和目的文件名,尽可能使用标准I/O和二进制模式 */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc,char *argv[]){ char buf[1024] = {0}; int s = 0; FILE * fp01; //sources file FILE * fp02; //target file if(argc != 3){ printf("输入错误:\n"); printf("例如:test.exe 1.txt 2.txt\n"); exit(1); } if((fp01 = fopen(argv[1],"rb")) == NULL){ printf("不能打开%s文件\n",argv[1]); exit(1); } fp02 = fopen(argv[2],"wb"); while(!feof(fp01)){ memset(buf,0,sizeof(buf)); size_t res = fread(buf,sizeof(char),sizeof(buf),fp01); fwrite(buf,sizeof(char),res,fp02); s += res; printf("复制%d字节\n",s); } fclose(fp01); fclose(fp02); printf("Done"); return 0; }
/* * 3.编写一个文件复制程序,提示用户输入源文件名和目的文件名,尽可能使用标准I/O和二进制模式 * 在向输出文件写入时,程序应当使用cype.h中的toupper()函数将所有的文本转换为大写。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> int main(int argc,char *argv[]){ char buf = 0; int s = 0; FILE * fp01; //sources file FILE * fp02; //target file char f01[20] = { 0 }; char f02[20] = { 0 }; printf("请输入源文件名称:\n"); scanf("%s",f01); printf("请输入目标文件名称:\n"); scanf("%s",f02); if((fp01 = fopen(f01,"r")) == NULL){ printf("不能打开%s文件\n",f01); exit(1); } fp02 = fopen(f02,"w"); while((buf = fgetc(fp01)) != EOF){ fputc(toupper(buf),fp02); s++; printf("复制%d字符\n",s); } fclose(fp01); fclose(fp02); printf("Done"); return 0; }
/* * 4.编写一个程序,依次在屏幕上显示命令行中列出的全部文件,使用argc控制循环。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc,char *argv[]){ char ch; if(argc < 2){ printf("No file!\n"); exit(1); } for(int i = 1;i<argc;i++){ FILE * fp = fopen(argv[i],"r"); printf("show file %d:%s\n",i,argv[i]); puts("-------------------------------"); while((ch = fgetc(fp))!= EOF){ putchar(ch); } puts("\n-------------------------------"); fclose(fp); } printf("Done"); return 0; }
/* * 5.修改程序清单13.6中的程序,使用命令行参数(而不是交互式界面)获得文件名 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFSIZE 1024 #define SLEN 81 void append(FILE *source,FILE *dest); int main(int argc,char *argv[]){ FILE *fa,*fs; int files = 0; char file_app[SLEN]; char file_src[SLEN]; if(argc < 3){ printf("命令行中的文件数量必须>=2。\n"); exit(2); } //file_app = argv[argc-1]; strcpy(file_app,argv[argc-1]); if((fa = fopen(file_app,"a")) == NULL){ fprintf(stderr,"Can't open %s.\n",file_app); exit(2); } if(setvbuf(fa,NULL,_IOFBF,BUFSIZE) != 0){ fputs("Can't create output buffer\n",stderr); exit(3); } for(int i= 1;i < argc-1;i++){ //file_src = argv[i]; strcpy(file_src,argv[i]); if(strcmp(file_src,file_app) == 0){ fputs("Can't append file to itself\n",stderr); }else if((fs = fopen(file_src,"r")) == NULL){ fprintf(stderr,"Can't open %s.",file_src); }else{ if(setvbuf(fs,NULL,_IOFBF,BUFSIZE) != 0){ fputs("Can't create input buffer\n",stderr); continue; } append(fs,fa); if(ferror(fs) != 0) fprintf(stderr,"Error in reading file %s.\n",file_src); if(ferror(fa) != 0) fprintf(stderr,"Error in reading file %s.\n",file_app); fclose(fs); printf("File %s appended.\n",file_src); files++; } } printf("Done, %d files appended.\n",files); fclose(fa); return 0; } void append(FILE *source,FILE *dest){ size_t bytes; static char temp[BUFSIZE]; while((bytes = fread(temp,sizeof(char),BUFSIZE,source)) > 0) fwrite(temp,sizeof(char),bytes,dest); }
/* * 6.重写程序清单13.2中的程序,不使用命令行参数,而是提示用户输入所需要的信息 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define LEN 40 int main(void){ FILE *in,*out; int ch; char name1[LEN] = {0}; char name2[LEN] = {0}; int count = 0; printf("请输入将要压缩的文件名称:\n"); scanf("%s",name1); if((in = fopen(name1,"r")) == NULL){ fprintf(stderr,"不能打开%s文件\n",name1); exit(1); } strcpy(name2,name1); strcat(name2,".red"); if((out = fopen(name2,"w")) == NULL){ fprintf(stderr,"不能打开%s文件\n",name2); exit(2); } while((ch = getc(in)) != EOF) if(count++ % 3 == 0) putc(ch,out); if(fclose(in) != 0 || fclose(out) != 0) fprintf(stderr,"Error in closing files\n"); return 0; }
<pre name="code" class="cpp">/* * 7.编写一个打开两个文件的程序,可以使用命令行参数或者请求用户输入来获得文件名。 * a.让程序打印第一个文件的第一行,第二个文件的第一行,第一个文件的第二行,第二个文件的第二行,依此类推, * 直到打印完行数较多的的文件的最后一行。 * b.修改程序,把行号相同的行打印到同一行上。 * test.exe <file1> <file2> <a|b> */ #include <stdio.h> #include <stdlib.h> #include <string.h> void del_li(char *s); //删除换行符 int main(int argc,char *argv[]){ char mode = 'a'; char name01[20] = {0}; char name02[20] = {0}; char row[100] = {0}; FILE *fp1,*fp2; if(argc <= 1){ printf("请输入文件一名称:\n"); scanf("%s",name01); printf("请输入文件二名称:\n"); scanf("%s",name02); }else if(argc == 2){ strcpy(name01,argv[1]); printf("请输入文件二名称:\n"); scanf("%s",name02); }else if(argc == 4){ strcpy(name01,argv[1]); strcpy(name02,argv[2]); mode = argv[3][0]; } fp1 = fopen(name01,"r"); fp2 = fopen(name02,"r"); while(!feof(fp1) || !feof(fp2)){ if(!feof(fp1)){ memset(row,0,sizeof(row)); fgets(row,sizeof(row),fp1); if(mode == 'b') del_li(row); printf("%s",row); } if(!feof(fp2)){ memset(row,0,sizeof(row)); fgets(row,sizeof(row),fp2); if(mode == 'b') del_li(row); printf("%s",row); } if(mode == 'b') printf("\n"); } fclose(fp1); fclose(fp2); return 0; } void del_li(char *s){ char * i; if((i = strchr(s,'\n')) != NULL) *i = 0; }
/* * 8.编写一个程序,将一个字符、零个或多个文件名作为命令行参数。如果字符后没有参数跟随,程序读取标准输入文件,否则 * ,程序依次打开每个文件,然后报告每个文件中该字符出现数。文件名与该字符本身也与计数值一起报告。程序中包含错误检查 * ,以确定参数的数目是否正确和是否能打开文件,如果不能打开,程序要报告这一情况,然后转入处理下一个文件。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define COLS 81 unsigned int count(FILE *fp, char ch); //统计fp文件中ch字符的个数 int main(int argc, char *argv[]) { FILE *fp; char ch; char name[COLS]; if (argc <= 2) { if (argc == 1) { printf("请输入要统计的字符:"); scanf("%c", &ch); } else ch = argv[1][0]; printf("请输入要统计的文件名称:\n"); while (scanf("%s", name) != 0) { if (strcmp(name, "exit") == 0) break; fp = fopen(name, "r"); if (fp == NULL) { fprintf(stderr, "文件%s打开失败.\n", name); } else { fprintf(stdout, "文件%s包含%u个%c字符\n", name, count(fp, ch), ch); } fclose(fp); printf("请输入要统计的文件名称:\n"); } } else if (argc > 2) { ch = argv[1][0]; for (int i = 2; i < argc; i++) { fp = fopen(argv[i], "r"); if (fp == NULL) { fprintf(stderr, "文件%s打开失败.\n", argv[i]); } else { fprintf(stdout, "文件%s包含%u个%c字符\n", argv[i], count(fp, ch), ch); } fclose(fp); } } return 0; } unsigned int count(FILE *fp, char ch) { unsigned int i = 0; char dch; while ((dch = fgetc(fp)) != EOF) { if (dch == ch) i++; } return i; }
/* * 9.修改程序清单13.3中的程序,从1开始,根据加入列表的顺序为每个单词编号,当再次运行程序时,确保新的单词编号接着前面的编号开始。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 int main(void){ int n = 0; char ch; FILE * fp; char words[MAX]; if((fp = fopen("words.txt","a+")) == NULL){ fprintf(stdout,"Can't open \"words\" files.\n"); exit(1); } puts("Enter words to add to the files:press the Enter"); puts("key at the begining of a line to terminate."); /*while(gets(words) != NULL && words[0] != '\0'){ fprintf(fp,"%s ",words); }*/ long int i= 0; while(fseek(fp,i,SEEK_END) ==0){ ch = getc(fp); if(ch==':') break; i--; } i=0; while(fseek(fp,i,SEEK_CUR) == 0){ ch = getc(fp); if(ch==' ') break; i--; } if(fscanf(fp,"%s",words) == 1){ n = atoi(words); } fseek(fp,0L,SEEK_END); while(scanf("%s",words) == 1){ if(strcmp(words,"exit") == 0 ) break; n++; fprintf(fp,"%d:%s ",n,words); memset(words,0,sizeof(words)); fflush(fp); } puts("File contents:"); rewind(fp); while(fscanf(fp,"%s",words) == 1) puts(words); if(fclose(fp) != 0) fprintf(stderr,"Error closing file\n"); return 0; }
/* * 10.编写一个程序,打开一个文本文件,文件名通过交互方式获得,建立一个循环,请求用户输入一个文件位置,然后程序打印 * 文件中从该位置开始到下一换行符之间的部份,用户通过输入非数字字符来终止输入循环。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 long int filesize(FILE *fp); int main(void) { long int lines = 0; char name[MAX] = { 0 }; FILE *fp; printf("Enter file name:"); gets(name); if ((fp = fopen(name, "r")) == NULL) { fprintf(stderr, "Can't open %s file.", name); exit(1); } printf("Enter line number:"); while (scanf("%ld", &lines) != 0) { if (lines < filesize(fp)) { if (fseek(fp, lines, SEEK_SET) == 0) { memset(name, 0, sizeof(name)); fgets(name, MAX, fp); fprintf(stdout, "%s\n", name); } } else { fprintf(stdout, "can't find line number:%ld\n", lines); } printf("Enter line number(exit q):"); } if (fclose(fp) != 0) { fprintf(stderr, "Error in closing files\n"); exit(2); } return 0; } long int filesize(FILE *fp) { long int s = 0; fseek(fp, 0L, SEEK_END); s = ftell(fp); rewind(fp); return s; }
/* * 11.编写一个程序,接受两个命令行参数,第一个参数为一个字符串,第二个为文件名,程序打印文件中包含该字符串的 * 所有行。因为这一个任务是面向行而不是面行字符的,所以要使用fgets(),而不是getc(),使用标准C库函数strstr() * 在每一行中搜索这一字符串 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 int main(int argc,char * argv[]) { char buf[MAX] = { 0 }; FILE *fp; if(argc < 3 || argc > 3){ fprintf(stderr, "Error input.\n"); exit(1); } if((fp = fopen(argv[2],"r")) == NULL){ fprintf(stderr, "Can't open %s file.\n",argv[2]); exit(2); } printf("find:%s,file:%s\n",argv[1],argv[2]); while(!feof(fp)){ memset(buf,0,sizeof(buf)); fgets(buf,MAX,fp); if(strstr(buf,argv[1]) != NULL) printf("%s",buf); } if (fclose(fp) != 0) { fprintf(stderr, "Error in closing files\n"); exit(3); } return 0; }
/* * 12.创建一个包含20行,每行30个整数的文本文件,整数在0到9之间,用空格分开,该文件是一个图片数字的表示,从0到9的值 * 代表逐渐增加的灰度,编写一个程序,将文件的内容读入到一个20*30的int数组中,一种将这种数字表示转化成图片的粗略方法 * 就是让程序使用数组中的数值来初始化一个20*31的字符阵列。0对应空格字符,1对应句号字符,依此类推,较大的值对应占用 * 空间较多的字符,比如可以使用#代表9,每行的最后一个字符是空字符(第31个字符),这样数组将包含20个字符串,然后程序 * 显示结果图片(即打印这些字符串),并将结果存入一个文本文件中。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define ROW 20 //数组行数 #define CLO 30 //数组列数 char itoc(int s); //将s转换为指定的字符 int main(int argc,char * argv[]) { int num = 0; int image[ROW][CLO] = { 0 }; char imagechar[ROW][CLO+1] = {0}; FILE *fp = fopen("1.txt","r"); FILE *fp1 = fopen("2.txt","w"); for(int i=0;i<ROW;i++){ for(int j=0;j<CLO;j++){ fscanf(fp,"%d",&num); image[i][j] = num; imagechar[i][j] = itoc(num); printf("%c",imagechar[i][j]); } imagechar[i][CLO] = '\n'; fprintf(fp1,"%s",&imagechar[i]); printf("\n"); } fclose(fp); fclose(fp1); return 0; } char itoc(int s){ char chs[10] = " .'=%@*$#t"; return chs[s]; }
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 1 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 1 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
/* * 13.数字图像,尤其是从宇宙飞船发回的数字图像可能会包含尖峰脉冲,为第12道编程练习题添加消除尖峰脉冲的函数,该函数应该将每一值和它上下左右相邻的值比较, * 如果该值与它周围每个值的差都大于1,就用所有相邻值的平均值(取与其最接近的整数)取代这个值。注意到边界上的点相邻点少于4个所以它需要特殊处理。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define ROW 20 //数组行数 #define CLO 30 //数组列数 char itoc(int s); //将s转换为指定的字符 void xiao(int row,int clo,int image[row][clo]); int y4(int n,int tt ); //如果所有元素都大于等于1,如果大于则返回1,否则返回0 int main(int argc, char * argv[]) { int num = 0; int image[ROW][CLO] = { 0 }; char imagechar[ROW][CLO + 1] = { 0 }; FILE *fp = fopen("1.txt", "r"); FILE *fp1 = fopen("2.txt", "w"); for (int i = 0; i < ROW; i++) { for (int j = 0; j < CLO; j++) { fscanf(fp, "%d", &num); image[i][j] = num; imagechar[i][j] = itoc(num); printf("%c", imagechar[i][j]); } imagechar[i][CLO] = '\n'; fprintf(fp1, "%s", &imagechar[i]); printf("\n"); } fclose(fp); fclose(fp1); printf("\n\n-----图像尖峰处理------\n\n"); FILE *fp4 = fopen("3.txt", "w"); //对图像进行尖峰处理 xiao(ROW, CLO, image); memset(imagechar,0,sizeof(imagechar)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < CLO; j++) { //printf("%d",image[i][j]); imagechar[i][j] = itoc(image[i][j]); //printf("%c", imagechar[i][j]); } imagechar[i][CLO] = '\n'; fprintf(fp4, "%s", &imagechar[i]); //printf("\n"); printf("%s",imagechar[i]); } fclose(fp4); return 0; } char itoc(int s){ char chs[10] = " .'=%@*$#t"; return chs[s]; } void xiao(int row,int clo,int image[row][clo]){ int i = 0; int j = 0; int temp[4] = {0}; //存放与上下左右相减的绝对值 for(i=0;i<row;i++){ for(j=0;j<clo;j++){ if(i == 0){ if(j==0){ temp[0] = abs(image[i][j]-image[i+1][j]); //下值 temp[1] = abs(image[i][j]-image[i][j+1]); //右值 if(y4(2,temp)) image[i][j] = (image[i+1][j] + image[i][j+1])/2; //矩阵的左上角 }else if(j==clo-1){ temp[0] = abs(image[i][j]-image[i][j-1]); //左值 temp[1] = abs(image[i][j]-image[i+1][j]); //下值 if(y4(2,temp)) image[i][j] = (image[i][j-1] + image[i+1][j])/2; //矩阵的右上角 }else{ //矩阵上边 temp[0] = abs(image[i][j]-image[i][j-1]); //左值 temp[1] = abs(image[i][j]-image[i][j+1]); //右值 temp[2] = abs(image[i][j]-image[i+1][j]); //下值 if(y4(3,temp)) image[i][j] = (image[i][j-1] + image[i][j+1] + image[i+1][j])/3; //矩阵的上条边 } }else if(i == row - 1){ if(j == 0){ temp[0] = abs(image[i][j]-image[i-1][j]); //上值 temp[1] = abs(image[i][j]-image[i][j+1]); //右值 if(y4(2,temp)) image[i][j] = (image[i-1][j] + image[i][j+1])/2; //矩阵的左下角 }else if(j==clo-1){ temp[0] = abs(image[i][j]-image[i][j-1]); //左值 temp[1] = abs(image[i][j]-image[i-1][j]); //上值 if(y4(2,temp)) image[i][j] = (image[i][j-1] + image[i-1][j])/2; //矩阵的右下角 }else{ //矩阵下边 temp[0] = abs(image[i][j]-image[i][j-1]); //左值 temp[1] = abs(image[i][j]-image[i][j+1]); //右值 temp[2] = abs(image[i][j]-image[i-1][j]); //上值 if(y4(3,temp)) image[i][j] = (image[i][j-1] + image[i][j+1] + image[i-1][j])/3; //矩阵的下条边 } }else if(j==0){ temp[0] = abs(image[i][j]-image[i-1][j]); //上值 temp[1] = abs(image[i][j]-image[i+1][j]); //下值 temp[2] = abs(image[i][j]-image[i][j+1]); //右值 if(y4(3,temp)) image[i][j] = (image[i-1][j] + image[i+1][j] + image[i][j+1])/3; //矩阵的左条边 }else if(j==clo-1){ temp[0] = abs(image[i][j]-image[i-1][j]); //上值 temp[1] = abs(image[i][j]-image[i+1][j]); //下值 temp[2] = abs(image[i][j]-image[i][j-1]); //左值 if(y4(3,temp)) image[i][j] = (image[i-1][j] + image[i+1][j] + image[i][j-1])/3; //矩阵的右条边 }else{ temp[0] = abs(image[i][j]-image[i-1][j]); //上值 temp[1] = abs(image[i][j]-image[i+1][j]); //下值 temp[2] = abs(image[i][j]-image[i][j-1]); //左值 temp[3] = abs(image[i][j]-image[i][j+1]); //右值 if(y4(4,temp)) image[i][j] = (image[i-1][j] + image[i+1][j] + image[i][j-1] +image[i][j+1])/4; //矩阵内部 } } } } int y4(int n,int tt ){ for(int i=0;i<n;i++){ if(tt[i] <= 1) return 0; } return 1; }
相关文章推荐
- HDU 2222 — Keywords Search
- 二叉树遍历的应用(路径和问题,判断是否是二叉搜索树,判断是否是二叉平衡树)
- 使用串口AT命令驱动点阵屏 VFD
- 在jdk为1.6或1.7下,eclipse仍然报Remove '@override' annotation错误
- Android-基本控件(Toast 全解)
- Python 爬虫入门《上》
- Jenkins_Maven_Git 持续集成及自动化部署 GentOS版
- 移动WEB开发入门学习笔记
- VMware Workstation(虚拟机)v10.0.1 简体中文破解版
- 几何编程题
- 自增运算
- printf支持的格式
- 数组中出现次数超过一半的数字(算法)
- 大龄屌丝自学笔记--Java零基础到菜鸟--011
- PHP扩展模块安装
- URI(URL) 允许的字符
- HDOJ 1005 Number Sequence(规律)
- PXE安装 系统
- BZOJ2773
- python爬取ajax动态生成的数据 以抓取淘宝评论为例子