《C Primer Plus(第五版)中文版》第13章第1至13题

来源:互联网 发布:黄貂鱼无人机知乎 编辑:程序博客网 时间:2024/06/05 23:47
/* * 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 fileFILE * fp02; //target fileif(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 fileFILE * fp02; //target filechar 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 81void 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 40int 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 81unsigned 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);} elsech = 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 100int 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 100long 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 100int 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 10 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 10 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 00 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 00 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 00 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 00 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 05 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 58 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 89 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 98 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 85 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 50 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 00 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 00 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 00 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 00 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 00 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 00 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 00 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[n]); //如果所有元素都大于等于1,如果大于则返回1,否则返回0int 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[n]){for(int i=0;i<n;i++){if(tt[i] <= 1) return 0;}return 1;}




                                             
0 0
原创粉丝点击