字符串处理

   一.实验目的

    熟悉并掌握字符串的处理技术,熟悉并掌握文本文件的操作技术,进而对一般的文字处理软件的设计方法有所了解。

   二.实验题目

1.统计一篇英文小说中单词的个数。

2.语言文字研究人员常常需要对某些词汇的使用频率进行统计。试帮助他们设计一个程序,统计某篇英文小说中某些词汇的出现次数和位置。设英文小说已存于一个文本文件中,待统计的词汇集要一次输入完毕,即统计工作应在程序的一次运行之后全部完成。程序的输出结果是每个词的出现次数以及出现位置所在行的行号。

说明:英文小说必须存储在文件或数据库中。

三.实现提示

1.出现位置所在行的行号可以用链表存储。若某词在某行中出现了不止一次,不必存多个相同的行号。

2.待统计词汇可以完全由小写字母组成,但文本文件中或许存在大写字母,程序应能够识别并予以正确统计。

3. 下表中列出的用于文件操作的C标准函数可以在程序中调用。

标识符

类型

功  能

fopen

函数

用于打开一个外部文件

fgetc

函数

从外部文件读取一个字符

fclose

函数

用于关闭一个文件

EOF

变量

用于判断文件是否结束

其中,fopen的调用方式为 fp=fopen(filename,"r")),filename指定要打开的外部文件名,它是一个字符串类型的常量,“r”指定文件的打开方式为只读打开。返回值fp为一个FILE* 类型的指针,指向被打开的文件。fgetc的调用方式为c=fgetc(fp),c为读取得字符。

下面是一个程序片断,该程序的功能是显示上文本文件readme.txt的内容。

if((fp=fopen(“readme.txt”,"r"))==NULL)

{

cout<<"Cannot openfile."<<endl;

}

c=fgetc(fp);

while(c!=EOF)//文本没结束

{

    c=fgetc(fp);

     cout<<c;

}


/*
	1.统计英文单词的数量
	2.统计单词出现的次数和出现的位置
		a.可以用链表存储出现的位置,如果同一行出现很多单词,可以不用存储多个行号 
		b.文件中字母大小写应该进行识别,即不区分大小写 
*/

#include <stdio.h>
#include <tchar.h> 
#include "string.h"  
#include <malloc.h>  

typedef struct _State{
	int h;
	int r;
	_State* next;
}State;
  
typedef struct _link        // 定义该链表是为了存储不重复出现的单词  
{ 
	State* state; 
    char* ch;  
    int num;  
    _link* next;  
}link;

int main(int argc, _TCHAR* argv[])  
{  
	//文件游标创建和初始化 
	State* my_state=(State*)malloc(sizeof(State));	
	my_state->h=0;
	my_state->r=1;
	
	
    // 读入一个txt.文件操作  
    FILE *fp;  
    fp = fopen("test3.txt","r");
    char word[1025];  //最后一位用来存放“\0” \0是字符串的结束符 
    int pos = 0;        // 亦可用 size_t类型  
    char c;  
    link *head, *pnow, *ptmp;  
    head = pnow = ptmp = NULL;  
    while (!feof(fp))  
    {  	 
        c = fgetc(fp);
        my_state->h++;//读取字符后h游标加1,和while判断是否换行想对应 
		/*
		if(c=='\n'){
			my_state->h=0;
			my_state->r++;
		}
		else{
			my_state->h++;
			
		}
		*/
		
        if ((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c=='\'')) {
        	//将大写字母换成小写字母 
			if(c>='A'&&c<='Z'){
        		c=c+32;
			}
        	word[pos++]=c;  
		} 
        //pos>0解决了可能存在多个空格的情况"    " 
        else if (pos>0)  
        {  
            word[pos] = '\0';  
            // 链表遍历,比较链表中的节点值与当前单词  
            ptmp = head;  
            while (ptmp)  
            {  
                if (strcmp(word, ptmp->ch)==0)  
                {
					//找坐标 。并创建链表存储 
					State* state=(State*)malloc(sizeof(State));	  
					state->h=my_state->h;
					state->r=my_state->r;
					state->next=NULL;
					State* p=ptmp->state;
					while(p!=NULL&&p->next!=NULL){
						p=p->next;
					}
					p->next=state;
					//单词数++ 
                    ptmp->num++;  
                    break; 
                }  
                ptmp = ptmp->next;  
            } 
			 
            // 如果链表中没有当前单词,在链表末尾插入节点  
            if (ptmp == NULL)  
            {  
            	
                ptmp = (link*)malloc(sizeof(link));
                
                //新单词首先要给一个坐标 
                State* state=(State*)malloc(sizeof(State));	  
				state->h=my_state->h;
				state->r=my_state->r;
				state->next=NULL;
			    ptmp->state=state;
					
                
                ptmp->ch = (char*)malloc(pos);  
                strcpy(ptmp->ch, word);  
                ptmp->num=1;  
                ptmp->next = NULL;  
                if (pnow)   // 插入当前节点为末节点  
                {  
                    pnow->next = ptmp;  
                    pnow = ptmp;  
                }  
                else        // 此处为第一次出现单词的时候  
                    head = pnow = ptmp;  
            }  
            pos=0;  
        }  
        if(c=='\n'){
			my_state->h=0;
			my_state->r++;
		}
        
    }  
    fclose(fp); // 对文件进行操作,关闭文件  
  
    // 读取链表,输出单词及其出现的个数  
    ptmp = head;  
    FILE *fp1 = fopen("text3_result.txt","w");  
    while (ptmp)  
    {  
        fprintf(fp1,"%d\t%s\t", ptmp->num, ptmp->ch);  
        State* p=ptmp->state;
		while(p!=NULL){
				fprintf(fp1,"(%d,%d)  ", p->r, p->h);  
				p=p->next;
		}
		fprintf(fp1,"\n");
        ptmp = ptmp->next;  
    }  
    fclose(fp1);  
  
    return 0;  
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值