C语言:如何实现在txt文件中删除超链接、统计单词数量、生成单词列表 (文本流操作并解决乱码)

1、首先读取原文件内容文本流(包含中英文)

2、删除超链接

3、统计单词数量

4、去除重复单词

读取文件需要自己在文本笔记中保存一个网页,保存为txt文件

注意的是,在这个代码实现过程中,我学到的是如何避免输入内容时出现乱码的现象,第一是必须要用fprintf、fread、fwrite等 用于文本流的函数,而不能用fputc、fputs这些用于二进制文本的函数,虽然说当你内容少的时候,可能不会出现乱码情况,当你输入内容多起来的时候就不一定了。(以上只是向txt文件输入内容的时候)

所以记住,fprintf是向txt文件原原本本的输出你想要输出的东西。

读取出现乱码怎么办:网上有很多说法,你可以试试保存txt文件的时候按照其他博客大佬那样修改保存的格式,

但是我这里使用的是系统命令,

也就是在int main(){后面加上一段代码:system("mode con cp select=65001");

代码表示,将代码页转换为UTF-8,因为计算机在读取内容的时候,是用二进制的方式读取,读进去的时候自然会有乱码现象,所以我们无须在文本文件下面另存为UTC-8类型(我自己另存了也不行,读出来还是会有乱码现象),所以我最后用命令行的方式解决了这个困扰我很久的世纪难题!!!!!!!!!!!!!!最后记得输出%d或者其他%lf等等数字的时候需要改回你自己计算机的代码页,我的是936,所以在输出多少个单词的时候再次用system命令行修改代码页

system("mode con cp select=65001");

   显示代码页:

   其中65001代表UTF-8,输出为:

    Status for device CON:
    ----------------------
    Lines:          9001
    Columns:        120
    Keyboard rate:  31
    Keyboard delay: 1
    Code page:      65001

       
  代码页就是DOS中显示的语言
    437代表美式英语即可输出为:
  Status for device CON:
  ----------------------
  Lines: 40
  Columns: 100
  Keyboard rate: 31
  Keyboard delay: 1
  Code page: 437
  936(936表示简体中文)输出:
  设备状态 CON:
  ---------
  行:  40
  列:  100
  键盘速度: 31
  键盘延迟:  1
  代码页: 936

#include<stdio.h>
#include<string.h>
#include<ctype.h>
/*
	/ ********************************************** /
		This is Jackson.W's Experiment report. 
		Time: 2022.03.05
		school num: 20203005129
	/ ********************************************** /
	
	
	//暂时不修改原文件内容
	-----------------------------
	创建一个临时文件,将源文件进行扫描,超链接不扫描,操作完成后再进行临时文件内容复制到原文件中,就可以实现源文件也删除了超链接 
	-----------------------------
	
	
	第一大功能实现: 
	将扫描到的字符串一个一个录入到字符串中,
	(删除超链接)
	创建一个临时文件,将源文件进行扫描,超链接不扫描
	
	1,若碰到 < 符号,判断是否是超链接
	
	2,设置一个函数,碰到的 < 的地方,在此处继续扫描下去,直到遇到 > 符号 
	
	3,记录此处的位置,继续录入字符到字符串中去 
	
	4,直到文件的末尾处 
	
	
	测试结果: 该文件的字符串长度:14254 
	
	第二大功能:将删除超链接后的文件内容复制到另一个文本中去 
	
	第三大功能:统计单词数目 
	
	第四大功能:去除重复单词
	a) 建立一个结构数组,包含:存字符串的数组, 计算单词数量int ,定义一个字符串数组copy,用来缓存文件单词 
	b) 读取第一个单词,录进copy中,再与结构数组的字符串进行比较 
	c) 如果不同,则存进第i个数组结构的字符串 
	d) 如果相同,就清空copy的字符串,再进行下一次的扫描 
	e) 
	 
	
	第五大功能:将单词表存进另一个txt文件  
	
*/

typedef struct _Wordc{
	char s[20];
	int num;
	
}Wordc;//定义两百个空间,录入单词 


void prt(char ch, FILE *fp);//输出文本内容 

void deltxt(char ch, FILE *fp, FILE *temp);//删除超链接 

void copytxt(char ch,  FILE *fp, FILE *null_f);//实现两个文件的复制,第一个内容复制到另一个文件内容中去 

int madeword(char *ch, FILE *fp);//实现将文件中的单词提取出来 

void wordcc(Wordc *wordc, FILE *fp1, FILE *fp2, char *copy);//去除重复单词,生成单词表打印出来

void wbiao(Wordc *wordc, FILE *fp, int m);

int main()
{
	int i;
	system("mode con cp select=65001");
	char ch;
	char ch1[20], ch2[20];
	//char *w[20];
	FILE *fp1 = NULL;
	FILE *fp2 = NULL;
	char copy[20];
	Wordc wordc[700];
	
	//FILE *tmpfp = NULL;
	//tmpfp = tmpfile();//临时文件,测试代码要用 
	
	
	
	
	
	/************输出原始文本内容**************/
	fp1 = fopen("/tmp/shuju.txt", "r");
	prt(ch, fp1);
	fclose(fp1);
	/**************************************/ 
	
	
	/************删除超连接***************/ 
	fp1 = fopen("/tmp/shuju.txt", "r");
	fp2 = fopen("/tmp/new.txt", "w"); 
	//deltxt(ch1, fp1, tmpfp);用临时文件测试,实现删除超链接 
	deltxt(ch, fp1, fp2);
	
	fclose(fp1);
	fclose(fp2);
	/*************************************/ 
	
	/***************删除超连接后,将文件复制到新的文本**************/
	fp1 = fopen("/tmp/shuju.txt", "w");
	fp2 = fopen("/tmp/new.txt", "r"); 
	copytxt(ch, fp2, fp1);
	fclose(fp1);
	fclose(fp2);
	/*************************************/ 
	
	/************输出删除超链接后的内容**************/
	fp1 = fopen("/tmp/shuju.txt", "r");
	prt(ch, fp1);
	fclose(fp1);
	/**************************************/ 
	
	/************统计单词数目,除去重复单词, 打印出单词相同的单词表,并且将单词表复制给新的文本里面*************/
	fp1 = fopen("/tmp/new.txt", "r");
	fp2 = fopen("/tmp/wordsclub.txt", "w");
	wordcc(wordc, fp1, fp2, copy);
	fclose(fp1); 
	fclose(fp2);
	/**********************************************************************************************************/ 
	
	/*将单词表所在文件的单词内容打印出来*/ 
	fp2 = fopen("/tmp/wordsclub.txt", "r");
	prt(ch, fp2);
	fclose(fp2);
	/*************************************/
//	printf("\n***************\n");
//	for(i = 0; i < 200; i++)
//	{
//		printf("%s ", wordc[i].s);
//		if(i % 10 == 0)
//		{
//			printf("\n");
//		}
//	 } 
	return 0;
}

void prt(char ch, FILE *fp)//输出文本内容 
{
	while(!feof(fp))
	{
		ch = fgetc(fp);
		//fscanf(fp, "%c", &ch);
		//fread(ch, 20, 1, fp);
		putchar(ch);
		//printf("%s", ch);
	}
	
}

void deltxt(char ch, FILE *fp, FILE *temp)//删除超链接 ,temp为另一个文件,可为临时文件,也可为另一个文件 
{
	char copy[11];
	//char ch;
	int i;
	int index; 
	char tcopy[11]; 
	while(!feof(fp))
	{
		
		//ch = getc(fp);//判断是否碰到<符号
		pos_1:
			for(i = 0; i < 10; i++)
			{
				copy[i] = ' ';
				tcopy[i] = ' ';
			}
			//copy[9] = '\0';
		i = 0;
		//fread(copy, 10, 1, fp);
		
		for(i = 0; i < 10; i++)
		{
			copy[i] = getc(fp);//读取 
			if(copy[i] == '<')//当读取到<的时候                kjihi<dvs>inini<fsdgg      vcgcnsfg> 
		{
			copy[i] = '\0';//让他结束扫描,直接把字符串写进去
			 
			fprintf(temp, "%s", copy);
			while(1)
			{
				ch = getc(fp);
			while(ch == '>')
			{
				goto pos_1;//当遇到>结尾的时候就继续跳到read处继续扫描 
			}
			}
			
			//putchar(ch);//测试打印出来是否删除了超链接 
			//putc(ch, temp);//写到临时文件里面去
			//fprintf(temp, "%s", ch); 
		}
		else if(i == 9)//当一直没遇到< 
		{
			copy[10] = '\0';
			fprintf(temp, "%s", copy); 
		}
		}
		
		
//		else 
//		{
//			while(ch != '>')//当还没到>符号的时候继续往下扫描 
//			{
//				//ch = getc(fp);
//			}
//		}
	}
	
		
}

int madeword(char *ch, FILE *fp)//实现将文件中的单词提取出来, 默认是在当前文件流中继续扫描下一个
{
	
	char chp;
	int i = 0;
	char temp;
	while(!feof(fp))
	{
		
		temp = getc(fp);
		//ch[i] = chp;
		//printf("\n*************%c*************\n", chp);
				if((temp >= 65 && temp <= 90) || (temp >= 97 && temp <= 122) ) //确定是字母 
			{
				chp = temp;
				i = 0;
				while(1)
				{
					
					ch[i] = chp;
					printf("%c", ch[i]);
					chp = getc(fp);
					if(!((chp >= 65 && chp <= 90) || (chp >= 97 && chp <= 122)))
					{
						i++;
						ch[i] = '\0';
						//printf("\n%s\t", ch);
						break;
					}
					i++;
				}
				break;
			}
			
		
		
	}
	
} 

void wordcc(Wordc *wordc, FILE *fp1, FILE *fp2, char *copy)//去除重复单词,生成单词表打印出来 
{
	/*
	typedef struct _Wordc{
	char s[20];
	int num;
	}Wordc;//定义两百个空间,录入单词
	四大功能:去除重复单词
	a) 建立一个结构数组,包含:存字符串的数组, 计算单词数量int ,定义一个字符串数组copy,用来缓存文件单词 
	b) 读取第一个单词,录进copy中,再与结构数组的字符串进行比较 
	c) 如果不同,则存进第i个数组结构的字符串 
	d) 如果相同,就清空copy的字符串,再进行下一次的扫描 
	e) 
	*/
	int i = 0,j = 0, m = 1;
	int k = 0;
	//copy[20] = "";
	int index = 0;//当前结果数组的最大下标
	char ch;//读取流的字符 
	
	int numwords =  0; 
	int num = 0;
	int start = 0;
	
	for (j = 0; j < 200; j++)
	{
		wordc[j].num = 0; //把结构体数组成员的num全部赋值为0
	}
	
	while(!feof(fp1))
	{
		
		
		ch = fgetc(fp1);
		if(isalpha(ch))
	{
		
		start = 1;//标志进来过这个语句,所以已经有一个字母开头,下面就可以利用这个条件进行判断
		if(isupper(ch))
		{
			ch = tolower(ch);
		 } 
		copy[i++] = ch;
	}
	else if(!isalpha(ch) && start == 1)//符合条件就开始搜索是否有相同单词 
	{
		copy[i] = '\0';//添加\0 变成字符串之后方便比较和其他操作 
		numwords++;
		start = 0;
		//printf("%s*******88\n", copy); 
		for(j = 0; j < m; j++)
		{
			
			 
			if(strcmp(copy, wordc[j].s) == 0)//表示出现过
			{
				wordc[j].num++;
				k = 0;//表示有重复单词 
				break;
			 }
			 else
			 { 
			 	k = 1;//遍历所有元素,无影响,因为碰到上面有重复的才会break,这里即使等于1 了也不会出来,继续遍历 
			  } 
		  }	
		if(k == 1)
		{
			for(j = 0; j < i + 1; j++)
			{
				wordc[m].s[j] = copy[j];
			}
			wordc[m].num++;//新成员加一
			m++;//移动到结构的下一个新空间 
		  }  
		  i = 0;
		  for(j = 0; j < 20; j++)
		  {
		  	copy[j] = ' ';//清空copy内的字符内容 
		  }  
		   
		 } 
	} 
	system("mode con cp select=936");
	printf("一共有%d个不同的单词\n" , m-1);
	printf("总单词数量:%d\n", numwords);
	//system("mode con cp select=65001");
	
//	for(j = 0; j < m; j++)
//	{
//		printf("%s\n", wordc[j].s);
//	}
	
	
	/**************************************************生成单词表的函数在这里**********************/	
	wbiao(wordc, fp2, m); 
}

void wbiao(Wordc *wordc, FILE *fp, int m)
{	
	//system("mode con cp select=437");
	int i ,j;
	for(i = 0; i < m; i++)
	{
		
		//fwrite(wordc[i].s, sizeof(wordc[i].s[0]), sizeof(wordc[i].s) / sizeof(wordc[i].s[0]), fp);
		fprintf(fp, "%s", wordc[i].s);//链表中已经把字符字符串化,所以直接每一个单词输出就行 
		fprintf(fp, " ");
		if(i % 10 == 0)
		{
			fprintf(fp, "\n");
			//putc()
		}
	}
	
	
	
 } 

 

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

竹等寒

谢过道友支持,在下就却之不恭了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值