文本文件英文单词的计数

来源:互联网 发布:究极风暴4官方优化补丁 编辑:程序博客网 时间:2024/06/09 17:05

大二课程设计中的一次小练习:
设计
 C  C++ 程序,统计英文文本文件中,出现了多少个单词,每个单词出现了几次。连续的英文字符都认为单词 (不包括数字 ) ,单词之间用空格或标点符号分隔。

单词解析部分应该可以用正则表达式的,之后会进行补充。

第一次发博文,大家多来指点下哇!


/*********************************************************************** * File Name: WordsCount.cpp * Author: 夜阳Version: 1.0 * Created: 2012-6-18 23:28:22 * Last Change: 2012-6-20 9:04:44 * Discription: 统计英文文本文件中,出现了多少个单词,每个单词出现了几次 * *  运行WordsCount.cpp *  第一步输入待检索文件名(如TUT.txt) *  第二步输入输出的文件名(如result.txt) *  检索结果保存在result.txt中 ***********************************************************************/#include <stdio.h>#include "SqList.h"// 线性表的存储与操作int pickword ( FILE *f, char *fword );int main(){    FILE *f1, *f2;    // 指定默认文件名,用字符串保存文件名,便于操作    const int MAX_FILENAME = 20;// 文件名长度    char fname1[MAX_FILENAME] = "TUT.txt";    char fname2[MAX_FILENAME] = "result.txt";    // 用户指定源文件名    printf ( "请指定源文件名(不超过%d个字符):", MAX_FILENAME );    scanf ( "%s", fname1 );    // 用户指定输出文件名    printf ( "请指定要输出结果的文件名(不超过%d个字符):", MAX_FILENAME );    scanf ( "%s", fname2 );    //打开文件    if ( ( f1 = fopen ( fname1, "r" ) ) == NULL )// 异常处理    {        printf ( "打开文件%s失败!\n", fname1 );        return 0;    }    else        printf ( "打开文件%s成功!\n", fname1 );    SqList L;// 建立线性表    SqListInit ( &L );// 初始化线性表    char fword[MAX_CHARACTER];// 使用fword数组保存文件中的单词    fword[MAX_CHARACTER - 1] = '\0';    int i = -1;// 设置i为插入位置    while ( !feof ( f1 ) )// 读文件未结束    {        int judge = pickword ( f1, fword );// 从f指向的文件中提取单词到fword中        if ( -1 == judge )// 数组越界时提示并退出        {            printf ( "存在单词字符长度超过数组界限\n" );            return -1;        }        if ( SqListBSearch ( &L, fword, i ) )// i返回插入位置或单词在线性表中位置        {            // 在线性表中找到该单词            L.elem[i].count++;// 单词出现次数加1        }        else        {            // 线性表中未找到该单词            SqListInsert ( &L, i, fword );// 在第i个位置上插入        }    }    // 打开文件fname2,将内容写入    if ( ( f2 = fopen ( fname2, "w" ) ) == NULL )// 异常处理    {        printf ( "写入文件%s失败!\n", fname2 );        return 0;    }    else        printf ( "文件已写入%s!\n", fname2 );    // 将结果写入f2指向的文件中    SqListPrint ( f2, fname1, &L );    // 关闭文件    fclose ( f1 );    fclose ( f2 );}int pickword ( FILE *f, char *fword )// 从f指向的文件中提取单词到fword中{    char ch;// ch储存待检测字符    for ( int j = 0 , flag = 0 ; !feof ( f ) ; )// 逐个对字符进行检测,flag用于标记,为0时表示单词中无字母    {        if ( j >= MAX_CHARACTER )// 判断数组是否越界        {            return -1;        }        ch = fgetc ( f );// 获取字符        if ( ch >= 'A' && ch <= 'Z' )// 大写字符转小写保存在fword数组中        {            fword[j++] = ch + 32;            flag = 1;        }        if ( ( ch >= 'a' && ch <= 'z' ) )// 小写字符保存在fword数组中        {            fword[j++] = ch;            flag = 1;        }        if ( '-' == ch && fword[j - 1] >= 'a' && fword[j - 1] <= 'z' )// 若单词中带连字符,将连字符保存在fword数组中        {            fword[j++] = ch;        }        if ( ! ( ( ch >= 'A' && ch <= 'Z' ) || ( ch >= 'a' && ch <= 'z' ) || '-' == ch )                && flag == 1 )// 过滤单词中的非字母字符        {            if ( fword[j - 1] == '-' )// 排除类似于 a- 的单词                fword[j - 1] = '\0';            fword[j] = '\0';// fword数组以'\0'结尾            return 0;        }    }}

/*********************************************************************** * File Name: SqList.h * Author: 夜阳Version: 1.0 * Created: 2012-6-18 10:25:27 * Last Change: 2012-6-19 21:36:53 * Discription: 顺序表的初始化,建立,插入,查找,相关结果输出 ***********************************************************************/#include <stdio.h>#include <malloc.h>#include <string.h>const int MAX_CHARACTER = 50;// 单词最大长度定为50(TUT.txt文中最长单词为production-education-researching)//函数结果状态代码#define TRUE1#define FALSE0#define OK1#define ERROR0#define OVERFLOW -2// 线性表的动态分配顺序存储结构#define LIST_INIT_SIZE 100// 线性表存储空间的初始分配量#define LISTINCREMENT 10// 线性表存储空间的分配增量// 顺序存储结构的线性表类型typedef struct{    char word[MAX_CHARACTER];// 存储单词,不超过50个字符    int count;// 单词出现次数} ElemType;typedef struct{    ElemType *elem;// 存储空间基址    int length;// 当前长度    int listsize;// 当前分配的存储容量(以sizeof(ElemType)为单位)} SqList;// 线性表的初始化int SqListInit ( SqList *L ){    // 构造一个空的线性表L    L->elem = ( ElemType * ) malloc ( LIST_INIT_SIZE * sizeof ( ElemType ) );    if ( !L->elem ) return OVERFLOW;// 存储分配失败    L->length = 0;    L->listsize = LIST_INIT_SIZE;    return OK;}// 线性表的插入int SqListInsert ( SqList *L, int i, char *fword ){    // 在顺序线性表L中第i个位置之前插入新的元素e    // i的合法值为1≤i≤L.Length + 1    if ( i < 0 || i > L->length )    {        printf ( "i的值不合法!" );        return ERROR;// i的值不合法    }    if ( L->length >= L->listsize )    {        // 当前存储空间已满,增加分配        ElemType *newbase = ( ElemType * ) realloc ( L->elem,                            ( L->listsize + LISTINCREMENT ) * sizeof ( ElemType ) );        if ( !newbase )            return OVERFLOW;// 存储分配失败        L->elem = newbase;// 新基址        L->listsize += LISTINCREMENT;// 增加存储容量    }    ElemType *p, *q;    q = &L->elem[i];    for ( p = &L->elem[L->length - 1]; p >= q; p-- )// 插入位置之后元素逐个右移    {        * ( p + 1 ) = *p;    }    strcpy ( q->word, fword );// 复制fword中的字符到L->elem[i-1].word中    L->elem[i].count = 1;// 设置计数初值为1    L->length++;// 表长增1    return OK;}// 线性表二分法查找int SqListBSearch ( SqList *L, char *sword, int &i ){    if ( L->length == 0 )// 当线性表为空时    {        i = 0;// i返回单词插入位置        return ERROR;    }    // 线性表不空时,在线性表L中查找元素sword,用i返回其在线性表中的位置    int low = 0, high = L->length - 1, mid = L->length;    while ( low <= high )    {        mid = ( low + high ) / 2;        int k = strcmp ( L->elem[mid].word, sword );        if ( k == 0 )// 待查单词sword等于中间值,找到待查元素        {            i = mid;            return OK;// 查找成功,函数返回值为1,用i返回所查元素在线性表中的位置        }        else if ( k > 0 )// 待查单词sword小于中间值,继续在前半区间进行查找        {            high = mid - 1;            i = low;        }        else// 待查单词sword大于中间值,继续在后半区间进行查找        {            low = mid + 1;            i = high + 1;        }    }    return ERROR;// 线性表中不存在待查元素,函数返回值为0,i返回单词插入位置}void SqListPrint ( FILE *f, char fname[], SqList *L ){    fprintf ( f, "文档 %s 中总计有%d个单词\n", fname, L->length );// 输出统计信息,L->length为单词个数    fprintf ( f, "序号  单词                 个数\n" );    for ( int i = 0, j = 1 ; i < L->length ; i++, j++ )// j-序号        fprintf ( f, "%-5d %-20s %d\n", j, L->elem[i].word, L->elem[i].count );}

结果显示:


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 鞭炮放一半不响怎么办 禁止鸣笛的地方鸣笛了怎么办 手被炮仗炸了怎么办 手被猴子抓伤了怎么办 炸东西剩的油怎么办 炸臭豆腐剩的油怎么办 油炸久了油发黑怎么办 炸鱼的时候粘锅怎么办 吃了葱蒜有味怎么办 哺乳期喝了抹茶怎么办 干炸小黄鱼凉了怎么办 烧鱼酱油放多了怎么办 夏天腿干燥起皮怎么办 螃蟹柿子同时吃了怎么办 柿子和螃蟹一起吃怎么办 螃蟹和柿子吃了怎么办 今天为什么很多网站打不开怎么办 网上报名人太多服务器卡怎么办 网站换了电脑打不开怎么办 感冒时后背发凉怎么办? 脚扭了脚背疼怎么办 五妙水仙膏干了怎么办 红苹果接不到任务了怎么办 我判刑了家里老母亲怎么办 离婚之前对方把财产转移怎么办 有人侵犯我的名誉权怎么办 耳朵被咬红肿了怎么办 孕29周呼吸困难怎么办 痔疮出血一个星期了怎么办 怀孕长了副乳该怎么办 备孕期间长痔疮怎么办 15年凌度智能钥匙全丢怎么办 西水开发商跑了怎么办 如果房子烂尾了怎么办 小斗鱼出生后喂年丰虾在缸底怎么办 脸上痘痘红肿痒怎么办 签证一定要写酒店地址怎么办 重庆的狗狗死了怎么办 村霸霸占土地该怎么办 母狗生不出来了怎么办 电视锁屏失败了怎么办?