c语言:文件操作与字符处理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言:文件操作与字符处理相关的知识,希望对你有一定的参考价值。
1109 文件操作与字符处理
1. 题目及题目分析
1.1 问题描述
在当前目录中存在文件名为"case1.in"(其中case后为数字1,不是字母l,写错提交后会判错)的文本文件,
其内容为一篇英文文章(以EOF作为结束标志)。现要求读取该文本文件内容,统计文章中每个单词出现的次数,
并输出出现次数最多的前5个单词及其出现次数(按出现次数由多到少的顺序输出,次数相同时按字典顺序输出,
不足5个单词时,按序输出全部单词)。程序中注意如下细节:
(1) 空格、标点符号与回车符起到分隔单词的作用。
(2)文章一行的末尾可能有连字符,出现连字符时,该行最末的字符串与下行最先出现的字符串构一个单词;
(3) 名词缩写算一个单词;
(4) 数字不算单词;
(5) 单词不区分大小写;
(6) 输出时单词全使用小写;
输入格式
文件case1.in中一篇英文文章,包含多段文字,单词数不超过10000,每个单词不超过20个字符
输出格式
按题意输出答案
输入样例
(如case1.in内容如下)
I am a student. My school is SCAU. It is a beau-
tiful university. I like it.
输出样例
a 2
i 2
is 2
it 2
am 1
我希望有详细的注释!!!!在线等~
文件的打开操作 fopen 打开一个文件
文件的关闭操作 fclose 关闭一个文件
文件的读写操作 fgetc 从文件中读取一个字符
fputc 写一个字符到文件中去
fgets 从文件中读取一个字符串
fputs 写一个字符串到文件中去
fprintf 往文件中写格式化数据
fscanf 格式化读取文件中数据
fread 以二进制形式读取文件中的数据
fwrite 以二进制形式写数据到文件中去
getw 以二进制形式读取一个整数
putw 以二进制形式存贮一个整数
文件状态检查函数 feof 文件结束
ferror 文件读/写出错
clearerr 清除文件错误标志
ftell 了解文件指针的当前位置
文件定位函数 rewind 反绕
fseek 随机定位
# 文件的打开
1.函数原型
FILE *fopen(char *pname,char *mode)
2.功能说明
按照mode 规定的方式,打开由pname指定的文件。若找不到由pname指定的相应文件,就按以下方式之一处理:
(1) 此时如mode 规定按写方式打开文件,就按由pname指定的名字建立一个新文件;
(2) 此时如mode 规定按读方式打开文件,就会产生一个错误。
打开文件的作用是:
(1)分配给打开文件一个FILE 类型的文件结构体变量,并将有关信息填入文件结构体变量;
(2)开辟一个缓冲区;
(3)调用操作系统提供的打开文件或建立新文件功能,打开或建立指定文件;
FILE *:指出fopen是一个返回文件类型的指针函数;
3.参数说明
pname:是一个字符指针,它将指向要打开或建立的文件的文件名字符串。
mode:是一个指向文件处理方式字符串的字符指针。所有可能的文件处理方式见表8.1
4.返回值
正常返回:被打开文件的文件指针。
异常返回:NULL,表示打开操作不成功。
例如:
//定义一个名叫fp文件指针
FILE *fp;
//判断按读方式打开一个名叫test的文件是否失败
if((fp=fopen("test","r")) == NULL)//打开操作不成功
printf("The file can not be opened.\n");
exit(1);//结束程序的执行
要说明的是:C语言将计算机的输入输出设备都看作是文件。例如,键盘文件、屏幕文件等。ANSI C标准规定,在执行程序时系统先自动打开键盘、屏幕、错误三个文件。这三个文件的文件指针分别是:标准输入stdin、标准输出stdout和标准出错 stderr。
* 文件的关闭
1. 函数原型
int fclose(FILE *fp);
2. 功能说明
关闭由fp指出的文件。此时调用操作系统提供的文件关闭功能,关闭由fp->fd指出的文件;释放由fp指出的文件类型结构体变量;返回操作结果,即0或EOF。
3. 参数说明
fp:一个已打开文件的文件指针。
4. 返回值
正常返回:0。
异常返回:EOF,表示文件在关闭时发生错误。
例如:
int n=fclose(fp);
*文件的读写操作
A. 从文件中读取一个字符
1. 函数原型
int fgetc(FILE *fp);
2. 功能说明
从fp所指文件中读取一个字符。
3. 参数说明
fp:这是个文件指针,它指出要从中读取字符的文件。
4. 返回值
正常返回: 返回读取字符的代码。
非正常返回:返回EOF。
B. 写一个字符到文件中去
1. 函数原型
int fputc(int ch,FILE *fp)
2. 功能说明
把ch中的字符写入由fp指出的文件中去。
3. 参数说明
ch:是一个整型变量,内存要写到文件中的字符(C语言中整型量和字符量可以通用)。
fp:这是个文件指针,指出要在其中写入字符的文件。
4. 返回值
正常返回: 要写入字符的代码。
非正常返回:返回EOF。例如,要往"读打开"文件中写一个字符时,会发生错误而返回一个EOF。
C. 从文件中读取一个字符串
1. 函数原型
char *fgets(char *str,int n,FILE *fp)
2. 功能说明
从由fp指出的文件中读取n-1个字符,并把它们存放到由str指出的字符数组中去,最后加上一个字符串结束符'\0'。
3. 参数说明
str:接收字符串的内存地址,可以是数组名,也可以是指针。
n: 指出要读取字符的个数。
fp:这是个文件指针,指出要从中读取字符的文件。
4. 返回值
正常返回:返回字符串的内存首地址,即str的值。
非正常返回:返回一个NULL值,此时应当用feof()或ferror()函数来判别是读取到了文件尾,还是发生了错误。例如,要从"写打开"文件中读取字符串,将
发生错误而返回一个NULL值。
D. 写一个字符串到文件中去
1. 函数原型
int fputs(char *str,FILE *fp)
2. 功能说明
把由str指出的字符串写入到fp所指的文件中去。
3. 参数说明
str:指出要写到文件中去的字符串。
fp:这是个文件指针,指出字符串要写入其中的文件。
4. 返回值
正常返回: 写入文件的字符个数,即字符串的长度。
非正常返回:返回一个NULL值,此时应当用feof()或ferror()函数来判别是读取到了文件尾,还是发生了错误。例如,要往一个"读打开" 文件中写字符串时,
会发生错误而返回一个NULL值。
E. 往文件中写格式化数据
1.函数原型
int fprintf(FILE *fp,char *format,arg_list)
2.功能说明
将变量表列(arg_list)中的数据,按照format指出的格式,写入由fp指定的文件。fprintf()函数与printf()函数的功能相同,只是printf()函数是将数据写入屏幕文件(stdout)。
3.参数说明
fp:这是个文件指针,指出要将数据写入的文件。
format:这是个指向字符串的字符指针,字符串中含有要写出数据的格式,所以该字符串成为格式串。格式串描述的规则与printf()函数中的格式串相同。
arg_list:是要写入文件的变量表列,各变量之间用逗号分隔。
4.返回值
无。
G. 以二进制形式读取文件中的数据
1. 函数原型
int fread(void *buffer,unsigned sife,unsigned count,FILE *fp)
2. 功能说明
从由fp指定的文件中,按二进制形式将sife*count个数据读到由buffer指出的数据区中。
3. 参数说明
buffer:这是一个void型指针,指出要将读入数据存放在其中的存储区首地址。
sife:指出一个数据块的字节数,即一个数据块的大小尺寸。
count:指出一次读入多少个数据块(sife)。
fp:这是个文件指针,指出要从其中读出数据的文件。
4.返回值
正常返回:实际读取数据块的个数,即count。
异常返回:如果文件中剩下的数据块个数少于参数中count指出的个数,或者发生了错误,返回0值。此时可以用feof()和ferror()来判定到底出现了什么
情况。
H. 以二进制形式写数据到文件中去
1. 函数原型
int fwrite(void *buffer,unsigned sife,unsigned count,FILE *fp)
2. 功能说明
按二进制形式,将由buffer指定的数据缓冲区内的sife*count个数据写入由fp指定的文件中去。
3. 参数说明
buffer:这是一个void型指针,指出要将其中数据输出到文件的缓冲区首地址。
sife:指出一个数据块的字节数,即一个数据块的大小尺寸。
count:一次输出多少个数据块(sife)。
fp:这是个文件指针,指出要从其中读出数据的文件。
4.返回值
正常返回:实际输出数据块的个数,即count。
异常返回:返回0值,表示输出结束或发生了错误。
I. 以二进制形式读取一个整数
1. 函数原型
int getw(FILE *fp)
2. 功能说明
从由fp指定的文件中,以二进制形式读取一个整数。
3. 参数说明
fp:是文件指针。
4. 返回值
正常返回:所读取整数的值。
异常返回:返回EOF,即-1。由于读取的整数值有可能是-1,所以必须用feof()或ferror()来判断是到了文件结束,还是出现了一个出错。
J. 以二进制形式存贮一个整数
1.函数原型
int putw(int n,FILE *fp)
2. 功能说明
以二进制形式把由变量n指出的整数值存放到由fp指定的文件中。
3. 参数说明
n:要存入文件的整数。
fp:是文件指针。
4. 返回值
正常返回:所输出的整数值。
异常返回:返回EOF,即-1。由于输出的整数值有可能是-1,所以必须用feof()或ferror()来判断是到了文件结束,还是出现了一个出错。
* 文件状态检查
A. 文件结束
(1) 函数原型
int feof(FILE *fp)
(2) 功能说明
该函数用来判断文件是否结束。
(3) 参数说明
fp:文件指针。
(4) 返回值
0:假值,表示文件未结束。
1:真值,表示文件结束。
B. 文件读/写出错
(1) 函数原型
int ferror(FILE *fp)
(2) 功能说明
检查由fp指定的文件在读写时是否出错。
(3) 参数说明
fp:文件指针。
(4) 返回值
0:假值,表示无错误。
1:真值,表示出错。
C. 清除文件错误标志
(1) 函数原型
void clearerr(FILE *fp)
(2) 功能说明
清除由fp指定文件的错误标志。
(3) 参数说明
fp:文件指针。
(4) 返回值
无。
D. 了解文件指针的当前位置
(1) 函数原型
long ftell(FILE *fp)
(2) 功能说明
取得由fp指定文件的当前读/写位置,该位置值用相对于文件开头的位移量来表示。
(3) 参数说明
fp:文件指针。
(4) 返回值
正常返回:位移量(这是个长整数)。
异常返回:-1,表示出错。
(5) 实例
* 文件定位
A. 反绕
(1) 函数原型
void rewind(FILE *fp)
(2) 功能说明
使由文件指针fp指定的文件的位置指针重新指向文件的开头位置。
(3) 参数说明
fp:文件指针。
(4) 返回值
无。(5) 实
B. 随机定位
(1) 函数原型
int fseek(FILE *fp,long offset,int base)
(2) 功能说明
使文件指针fp移到基于base的相对位置offset处。
(3)参数说明
fp:文件指针。
offset:相对base的字节位移量。这是个长整数,用以支持大于64KB的文件。
base:文件位置指针移动的基准位置,是计算文件位置指针位移的基点。ANSI C定义了base的可能取值,以及这些取值的符号常量。
(4)返回值
正常返回:当前指针位置。
异常返回:-1,表示定位操作出错。
* 关于exit()函数
1. 函数原型
void exit(int status)
2. 功能说明
exit()函数使程序立即终止执行,同时将缓冲区中剩余的数据输出并关闭所有已经打开的文件。
3. 参数说明
status:为0值表示程序正常终止,为非0值表示一个定义错误。
4. 返回值
无。
* 关于feof()函数
1. 函数原型
int feof(FILE *fp)
2. 功能说明
在文本文件(ASCII文件)中可以用值为-1的符号常量EOF来作为文件的结束符。但是在二进制文件中-1往往可能是一个有意义的数据,因此不能用它 来作为文件的结束标志。为了能有效判别文件是否结束,ANSI C提供了标准函数feof(),用来识别文件是否结束。
3. 参数说明
fp:文件指针。
4. 返回值
返回为非0值:已到文件尾。
返回为0值:表示还未到文件尾。 参考技术A #include <stdio.h>
#include <string.h>
struct wordkeep
char c[20];
int num;
word[10000];
int main()
FILE * fp;
fp = fopen("case1.in", "r");
char w[20],ch;
int i,m,j,k,t,f;
m = 1;
i = j = k = t = f = 0;
while ((ch = fgetc(fp)) != EOF)
//小写转大小
if (ch >= 'A' && ch <= 'Z') ch += 32;
if (ch >= 'a' && ch <= 'z')
w[i] = ch;
i++;
f = 1;
//如果不是字母的话,先判定是不是连字符。
else
if (ch == '-' && (ch = fgetc(fp)) == '\\n') f = 0;
else
if (f)
//已经找到一个完整的单词
w[i] = '\\0';
i = 0;
f = 0;
m = 0;
//在已有的单词中逐个对比
for (j = 0; j < k; j++)
if (strcmp(w, word[j].c) == 0)
m = 1;
break;
//找到则单词数加1
if (m) word[j].num++;
//没找到安放新单词
else
word[k].num = 1;
strcpy(word[k].c, w);
k++;
//输出前5个最多的单词
for (i = 0; i < k && i < 5; i++)
t = 0;
while (word[t].num == 0) t++;
for (j = 1; j < k; j++)
if (word[j].num > word[t].num) t = j;
else if (word[j].num == word[t].num)
if (strcmp(word[j].c, word[t].c) < 0) t = j;
printf("%s %d\\n", word[t].c, word[t].num);
//每个单词输出后,单词数就清零,不影响下次的查找。
word[t].num = 0;
fclose(fp);
return 0;
参考技术B //#include "stdafx.h"//vc++6.0加上这一行.
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
struct word//建立一个结构体记录单词及数量
char w[21];
int n;
;
int main(void)
struct word a[10000]="",0,,tmp;//声明一个10000个元素的结构体数组作记录空间
FILE *fp;
int x,i,j,k=1;
char wt[21],wh[21];
if((fp=fopen("case1.in","r"))==NULL)//打开文件
printf("Open the file failure...\\n");
exit(0);
while(fscanf(fp,"%s",wt),!feof(fp)) //读一个单词
if(wt[x=strlen(wt)-1]=='-')//这个“单词”末尾是'-'的话接着读后面的“单词”
wt[x]='\\0';
fscanf(fp,"%s",wh);
strcat(wt,wh);//把后面读到的“单词”与前面读到的拼为一个单词
for(i=0;i<=x;wt[i++]|=0x20);//把单词中的大写变为小写
if(wt[x]>'z' || wt[x]<'a')//单词末尾有标点符号的话去掉
wt[x]='\\0';
for(i=0;i<k;i++)//检查记录中是否已有刚读到的单词
if(strcmp(wt,a[i].w)==0)//有的话免记录,将记录数量增1,跳出
a[i].n++;
break;
if(i==k)//未检索到刚读到的单词则追加记录且将数量置1
strcpy(a[k].w,wt);
a[k++].n=1;
fclose(fp);//读完关闭文件
for(i=0;i<k;i++)//共建立了k条记录,对其进行按数量排序
for(x=i,j=x+1;j<k;j++)
if(a[x].n<a[j].n) x=j;
if(x!=i)
tmp=a[x];
a[x]=a[i];
a[i]=tmp;
for(i=0;i<k;i++)//对排序后的记录中数量相等的记录按字典排序
for(x=i,j=x+1;j<k;j++)
if(a[x].n==a[j].n && strcmp(a[x].w,a[j].w)>0) x=j;
if(x!=i)
tmp=a[x];
a[x]=a[i];
a[i]=tmp;
//以上两次排序都用的是选择法
printf("The result is as following:\\n");//输出前5项
for(i=0;i<5;printf("%-20s %d\\n",a[i++].w,a[i].n));
return 0;
本回答被提问者采纳 参考技术C 用C++的话这道题简直就是送分题
C语言编程题目文件高级应用与字符串高级操作
题目:
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:
以上是关于c语言:文件操作与字符处理的主要内容,如果未能解决你的问题,请参考以下文章