C语言编程题目(4)文件高级应用与字符串高级操作
题目:
0x01 从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,然后输出到一个磁盘文件"test.dat"中保存。输入的字符串以"!"结束。
0x02 有两个磁盘文件“A.dat”和“B.dat”,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件“C.dat”中。
0x04 统计一个英文文本文件中26个英文字母出现次数并按英文字母序输出统计结果,查找并替换此英文文本文件中某字符串。
0x05 统计一个英文文本文件中所有单词出现次数并按英文字母序输出统计结果,查找并替换此英文文本文件中某单词。
0x06 编写程序XMLtoTXT自动将XML文件email.xml转换为文本文件email.txt。命令行格式:XMLtoTXT email.xml email.txt。
代码1:
1 #include<ctype.h> 2 #include<stdio.h> 3 #include<string.h> 4 #include <stdlib.h> 5 int main() 6 { 7 char Buf[1024]; 8 char c; 9 int i=0; 10 FILE *fp; 11 fp = fopen("test.dat","w+");//写入文件 12 if (fp == NULL) 13 { 14 perror("Open file recfile"); 15 exit(1); 16 } 17 printf("Input string: "); //输入字符串 18 fgets(Buf,sizeof(Buf),stdin); 19 // 去除字符串的换行符、回车和感叹号 20 while(Buf[strlen(Buf)-1] == '\n' || Buf[strlen(Buf)-1] == '\r' 21 ||Buf[strlen(Buf)-1] == '!') 22 Buf[strlen(Buf)-1]='\0'; 23 while( i < strlen(Buf) ) //循环字符串每个字符求大写 24 { 25 c = (char)toupper(Buf[i]); 26 Buf[i] = c; 27 i++; 28 } 29 printf("Result is : "); 30 fputs(Buf,stdout); //输出到界面显示结果 31 fprintf(fp,"%s",Buf);//输入到文件内 32 printf("\nWrite to test.dat done!\n"); 33 fclose(fp); 34 return 0; 35 }
运行结果1:
代码2:
1 #include<stdio.h> 2 #include<string.h> 3 #include <stdlib.h> 4 void sort(char a[],int N) //冒泡排序 5 { 6 int i,j; 7 char t; 8 for(i=0;i<N;i++) 9 { 10 for(j=0;j<N;j++) 11 { 12 if(a[j]>a[i]) 13 { 14 t=a[i]; 15 a[i]=a[j]; 16 a[j]=t; 17 } 18 } 19 } 20 } 21 int main() 22 { 23 FILE *fp1 = fopen("A.dat", "r"); 24 FILE *fp2 = fopen("B.dat", "r"); 25 FILE *fp3 = fopen("C.dat", "w"); 26 27 char buf1[128],buf2[128],buf3[256]; 28 fgets(buf1,sizeof(buf1),fp1); //读取A.dat一行内容 29 fgets(buf2,sizeof(buf2),fp2); //读取B.dat一行内容 30 printf("Strlen(buf1)=%d,buf1 = ",strlen(buf1)); 31 fputs(buf1,stdout); //显示A.dat内容 32 printf("\nStrlen(buf2)=%d,buf2 = ",strlen(buf2)); 33 fputs(buf2,stdout); //显示B.dat内容 34 memcpy(buf3,buf1,strlen(buf1)); 35 strcat(buf3,buf2); //把A.dat、B.dat内容都拷贝到buf3字符缓冲区内 36 printf("\nStrlen(buf3)=%d,buf3 = ",strlen(buf3)); 37 fputs(buf3,stdout); //显示buf3内容 38 // 对字符串buf3排序 39 sort(buf3,strlen(buf3)); 40 printf("\nAfter sorted,strlen(buf3)=%d,buf3 = ",strlen(buf3)); 41 fputs(buf3,stdout); //输出屏幕显示buf3 42 fputs(buf3,fp3); //buf3输入文件C.dat内 43 fclose(fp1); 44 fclose(fp2); 45 fclose(fp3); 46 return 0; 47 }
运行结果2:
代码3:
1 #include <stdio.h> 2 #include <stdlib.h> 3 int main() 4 { 5 FILE *outfile,*infile; 6 char ch; 7 int i=1; //i代表行号,初始为第一行 8 infile = fopen("test1.c","r"); //读取源c文件 9 outfile = fopen("test2.c","w");//写入目标文件 10 fprintf(outfile, "%d ", i); //打印第一行行号 11 i++; 12 while(ch = fgetc(infile)) //依次读取字符 13 { 14 if(feof(infile)) //文件末尾则跳出循环,读完毕 15 break; 16 if (ch=='/'){ 17 ch = fgetc(infile); //再次读取一个字符 18 if (ch=='/'){ //注释‘//’,就反复读到行末尾 19 while(ch = fgetc(infile)){ 20 if(ch=='\n'){ 21 fputc(ch,outfile); 22 fprintf(outfile, "%d ", i++);//打印行号,跳出循环 23 break; 24 } 25 } 26 } 27 else if(ch=='*'){ // 注释'/* */',中间的内容被忽略 28 while (ch = fgetc(infile)){ 29 if(ch=='*'){ 30 ch = fgetc(infile); 31 if(ch=='/') //注释结束,跳出循环 32 break; 33 } 34 } 35 } 36 } 37 else if (ch=='\n'){ // 正常情况的换行,输入到文件并打印行号 38 fputc(ch,outfile); 39 fprintf(outfile, "%d ", i++); 40 } 41 else //非注释、非换行字符都直接输出到目标文件 42 fputc(ch,outfile); 43 } 44 fclose(infile); 45 fclose(outfile); 46 return 0; 47 }
运行结果3:
代码4:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <ctype.h> 5 struct Alpha //字母 结构体,字母本身和键值 6 { 7 char zm; 8 int number; 9 }table[26]; 10 //自定义的字符串替换函数(所有出现的匹配串都替换为目标串) 11 void strreplace(char * Src,char * From,char * To){ 12 int length_to,length_from; 13 char *sf,*se,endBuf[1024]={0}; 14 length_from = strlen(From); 15 length_to = strlen(To); 16 while(sf = strstr(Src,From)){ 17 if(NULL == sf) 18 break; 19 else 20 { 21 se = sf + length_from; 22 strcpy(endBuf,se); 23 memset(se,0,strlen(endBuf)); 24 memcpy(sf,To,length_to); 25 memcpy(sf+length_to,endBuf,strlen(endBuf)); 26 memset(endBuf,0,strlen(endBuf)); 27 } 28 } 29 } 30 31 int main() 32 { 33 char ch; 34 char ZMB[]="abcdefghijklmnopqrstuvwxyz\0"; 35 char buf[1024]={0},*from,*to; 36 int index = 0; 37 FILE *fp,*fp1,*fp2; 38 while(index<26){ //结构体表内容初始化,number都为0,字母分别是a~z 39 table[index].zm = ZMB[index]; 40 table[index].number = 0; 41 index++; 42 } 43 fp = fopen("c.txt","r"); 44 while(ch = fgetc(fp)) //循环读取字符 45 { 46 if(feof(fp)) 47 break; 48 ch = tolower(ch); //小写 49 if(ch >= 'a' && ch <= 'z') //是字母就更新结构体表统计频次 50 { 51 index = ch - 'a'; 52 table[index].number++; 53 } 54 } 55 index = 0; 56 while(index<26){ //输出统计结果 57 printf("Char '%c' appears %d times in file.\n",table[index].zm,table[index].number); 58 index++; 59 } 60 fclose(fp); 61 // 输入想要搜寻的串和被替换成为目标字符串 62 printf("Input string you shall find:\t"); 63 fgets(from,sizeof(from),stdin); 64 from = strtok(from,"\n"); //去除换行符 65 printf("Input string you shall replace to:\t"); 66 fgets(to,sizeof(to),stdin); //去除换行符 67 to = strtok(to,"\n"); 68 // 把替换的串重新从c.txt读出、写入新文件d.txt 69 fp1 = fopen("c.txt","r"); 70 fp2 = fopen("d.txt","w"); 71 while(!feof(fp1)) 72 { 73 fgets(buf,sizeof(buf),fp1); 74 strreplace(buf,from,to); //每一行都查找、替换目标串 75 fputs(buf,fp2); 76 memset(buf,0,sizeof(buf)); 77 } 78 fclose(fp1); 79 fclose(fp2); 80 // 把d.txt内容写入c.txt 81 fp1 = fopen("c.txt","w"); 82 fp2 = fopen("d.txt","r"); 83 while(!feof(fp2)) 84 { 85 fgets(buf,sizeof(buf),fp2); 86 fputs(buf,fp1); 87 memset(buf,0,sizeof(buf)); 88 } 89 fclose(fp1); 90 fclose(fp2); 91 return 0; 92 }
运行结果4:
代码5:
1 #include <string.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <ctype.h> 5 struct word //单词结构体,单词长度最大为16 6 { 7 char name[16]; 8 char count; 9 }list[128]; //默认最多记录128个单词,可更改 10 //自定义的字符串替换函数(所有出现的匹配串都替换为目标串) 11 void strreplace(char * Src,char * From,char * To){ 12 int length_to,length_from; 13 char *sf,*se,endBuf[1024]={0}; 14 length_from = strlen(From); 15 length_to = strlen(To); 16 while(sf = strstr(Src,From)){ 17 if(NULL == sf) 18 break; 19 else 20 { 21 se = sf + length_from; 22 strcpy(endBuf,se); 23 memset(se,0,strlen(endBuf)); 24 memcpy(sf,To,length_to); 25 memcpy(sf+length_to,endBuf,strlen(endBuf)); 26 memset(endBuf,0,strlen(endBuf)); 27 } 28 } 29 } 30 31 int main() 32 { 33 char line_buf[1024]={0},word_buf[16]={0},*temp = NULL; 34 char local_list[128][16],from[16],to[16]; 35 int i=0,j=0,number=0,index=0,arr[128]={0}; 36 FILE *fp=NULL,*fp1=NULL,*fp2=NULL; 37 fp = fopen("e.txt","r"); 38 39 while(!feof(fp)) 40 { 41 fgets(line_buf,sizeof(line_buf),fp); //一行最多读取1024个字符 42 /*截取此行第一个单词*/ 43 temp = strtok(line_buf," "); 44 while((temp[strlen(temp)-1] == '.') || (temp[strlen(temp)-1] == ',') || \ 45 (temp[strlen(temp)-1] == '?') || (temp[strlen(temp)-1] == '!') || \ 46 (temp[strlen(temp)-1] == '\n')|| (temp[strlen(temp)-1] == '\r') ) 47 temp[strlen(temp)-1]='\0'; 48 while(i <= number) /*匹配结构体的所有单词内容*/ 49 { 50 if(strcmp(list[i].name,temp)==0){ //匹配成功,计数加一,跳出循环 51 list[i].count += 1; 52 break; 53 } 54 else if(i == 0 && number == 0){ //第一个单词很特殊,要单独初始化 55 strcpy(list[number].name, temp); 56 list[number].count ++; 57 number++; 58 break; 59 } 60 else if(i == number-1){ //最后一个单词都没匹配已有的单词成功,就单独填入结构体末尾 61 strcpy(list[number].name, temp); 62 list[number].count ++; 63 number++; 64 break; 65 } 66 i++; 67 } 68 i = 0; 69 /*截取此行第二个单词和以后的内容*/ 70 temp = strtok(NULL," "); 71 while(temp) 72 { //while循环去除但此后面的标点符号和换行符 73 while((temp[strlen(temp)-1] == '.') || (temp[strlen(temp)-1] == ',') || \ 74 (temp[strlen(temp)-1] == '?') || (temp[strlen(temp)-1] == '!') || \ 75 (temp[strlen(temp)-1] == '\n')|| (temp[strlen(temp)-1] == '\r') ) 76 temp[strlen(temp)-1]='\0'; 77 while(i < number) 78 { 79 if(strcmp(list[i].name,temp)==0){ 80 list[i].count += 1; 81 break; 82 } 83 if(i == number-1){ 84 strcpy(list[number].name, temp); 85 list[number].count ++; 86 number++; 87 break; 88 } 89 i++; 90 } 91 i = 0; 92 temp = strtok(NULL," "); 93 } 94 memset(line_buf,0,sizeof(line_buf)); 95 } 96 printf("Matched %d words successfully in struct.\n",number); 97 //把结构体的单词依次填入本地二维字符数组local_list 98 for(i = 0;i < number;i++){ 99 arr[i] = i; 100 strcpy(local_list[i],list[i].name); 101 } 102 // 对二维数组冒泡排序,并且arr数组标记新的顺序(结构体序号顺序) 103 for(i=0;i<number;i++){ 104 for(j=0;j<i;j++){ 105 if(strcmp(local_list[i],local_list[j])<0){ 106 strcpy(word_buf,local_list[i]); 107 strcpy(local_list[i],local_list[j]); 108 strcpy(local_list[j],word_buf); 109 memset(word_buf,0,strlen(word_buf)); 110 index = arr[i]; 111 arr[i] = arr[j]; 112 arr[j] = index; 113 } 114 } 115 } 116 i = 0; 117 // 按arr数组的顺序输出结果,单词因此是按照a->z的顺序写入的 118 while(i<number){ 119 printf("Word '%s' appears %d times\n",list[arr[i]].name,list[arr[i]].count); 120 i++; 121 } 122 fclose(fp); 123 memset(line_buf,0,sizeof(line_buf)); 124 //定义查找的字符串、替换成的字符串 125 printf("Input string you shall find:\t"); 126 fgets(from,sizeof(from),stdin); 127 strtok(from,"\n"); 128 printf("Input string you shall replace to:\t"); 129 fgets(to,sizeof(to),stdin); 130 strtok(to,"\n"); 131 // 写入f.txt 132 fp1 = fopen("e.txt","r"); 133 fp2 = fopen("f.txt","w"); 134 while(!feof(fp1)) //每次读取一行并且替换目标字符串 135 { 136 fgets(line_buf,sizeof(line_buf),fp1); 137 strreplace(line_buf,from,to); 138 fputs(line_buf,fp2); 139 memset(line_buf,0,sizeof(line_buf)); 140 } 141 fclose(fp1); 142 fclose(fp2); 143 return 0; 144 }
运行结果5:
代码6:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <ctype.h> 5 //函数用于去除字符串首尾的空格、制表符和回车、换行符等空白符号 6 void trim(char *strIn, char *strOut){ 7 char *start, *end, *temp;//定义去除空格后字符串的头尾指针和遍历指针 8 temp = strIn; 9 while (*temp == ' ' || *temp == '\n' || *temp == '\t' || *temp == '\r'){ 10 ++temp; 11 } 12 start = temp; //求得头指针 13 temp = strIn + strlen(strIn) - 1; //得到原字符串最后一个字符的指针(不是'\0') 14 printf("%c\n", *temp); 15 while (*temp == ' ' || *temp == '\n' || *temp == '\t' || *temp == '\r'){ 16 --temp; 17 } 18 end = temp; //求得尾指针 19 for(strIn = start; strIn <= end; ){ 20 *strOut++ = *strIn++; 21 } 22 *strOut = '\0'; 23 } 24 //字符串切割函数,src最后为截止到sub子串首次出现之前的内容 25 void strsplit(char *src , char *sub){ 26 char *ptr; 27 ptr = strstr(src,sub); 28 //fputs(ptr,stdout); 29 *ptr = '\0'; 30 } 31 32 int main(int argc, char const *argv[]) 33 { 34 FILE *fp1,*fp2; 35 char buf[1024]={0},res[1024],*sp=NULL; 36 if (argc != 3) 37 { 38 fprintf(stderr,"You should input three argument,like 'XMLtoTXT.exe email.xml email.txt'."); 39 return(-1); 40 } 41 fp1 = fopen(argv[1],"r"); 42 fp2 = fopen(argv[2],"w"); 43 while(!feof(fp1)) 44 { 45 fgets(buf,sizeof(buf),fp1); //依次读取一行 46 trim(buf,res); 47 if(strcmp(res,"<from>")==0){ //找关键字<from> 48 memset(buf,0,sizeof(buf)); 49 memset(res,0,sizeof(res)); 50 fgets(buf,sizeof(buf),fp1); 51 trim(buf,res); //去空格 52 strsplit(res,"</address>"); //去末尾 53 sp = strstr(res,"<address>"); 54 sp += strlen("<address>"); //sp指向真正想要的内容 55 fprintf(fp2,"from: %s\n",sp); //按照目标格式写入文件 56 memset(buf,0,sizeof(buf)); 57 memset(res,0,sizeof(res)); 58 continue; 59 } 60 if(strcmp(res,"<to>")==0){ //找关键字<to> 61 memset(buf,0,sizeof(buf)); 62 memset(res,0,sizeof(res)); 63 fgets(buf,sizeof(buf),fp1); 64 trim(buf,res); //去空格 65 strsplit(res,"</address>"); //去末尾 66 sp = strstr(res,"<address>"); 67 sp += strlen("<address>"); //sp指向真正想要的内容 68 fprintf(fp2,"to: %s\n",sp); //按照目标格式写入文件 69 memset(buf,0,sizeof(buf)); 70 memset(res,0,sizeof(res)); 71 continue; 72 } 73 if(sp=strstr(res,"</subject>")){ //找关键字</subject> 74 *sp = '\0'; //去末尾 75 sp = res + strlen("<subject>"); //sp指向真正想要的内容 76 fprintf(fp2,"subject: %s\n",sp);//按照目标格式写入文件 77 continue; 78 } 79 if(sp=strstr(res,"</body>")){ //找关键字</body> 80 *sp = '\0'; //去末尾 81 sp = res + strlen("<body>"); //sp指向真正想要的内容 82 fprintf(fp2,"body: %s\n",sp); //按照目标格式写入文件 83 break; 84 } 85 } 86 fclose(fp1); 87 fclose(fp2); 88 return 0; 89 }
运行结果6: