1、 问题描述
设计C++ 类,使其能够统计文本文件中字符个数,在终端中显示结果,并将结果保存到指定的文件中。需要统计的字符有: a 、英文字母总数 b 、英文单词总数从 c 、中文字符总数(包括标点符号) d 、行总数e 、其他字符总数(包括英文标点、空白符等)。
2、 问题分析
从问题描述中可以看到,我们所要做的就是将一篇文章(txt 格式,字符格式为 ANSI )中出现的中英文字符出现的次数进行统计。而一篇文本文件中出现的字符种类和顺序没有规律,如何对当前读取的字符的种类进行判断并转入到相应的统计状态成为了问题的关键。
但是,我们知道对于英文字母其ASCII 码范围在 65 ~ 90 和 97 ~ 122 两个区间,而英文单词的判断就是在相邻两个非英文字母之间夹着一串英文字母,所以我们可以在读取了第一个非英文字母后判断下一个读取的是否为英文字母,如果是便转入英文字符的处理状态,其中可同时对字母个数进行统计,在读到非英文字符时退出该状态,并将英文单词数加 1 ,然后转入“状态转换中心”进行状态转换的判断。
同理,对于中文字符的处理,也同上所述。但是由于中文字符占两个字节,而且各个编码格式中中文字符的编码范围不一致,所以处理起来比较麻烦,但是原理是一致的。在本例中仅对ANSI 格式的编码进行处理,所以中文字符每个字节的范围为 0x80 ~ 0xff ,不过在实际操作中发现有些中文字符还是被漏掉了,应该是中文字符的编码范围并没有全部包括进去的原因。
其他的字符处理没有什么难处,所以在此就不多述了。具体的见状态转换图吧。
3、 程序设计
首先,为类定义一个状态,如:
typedef enum{CHN,WORD,LIN,BOUND,PREPRO}SticState;
其中,CHN 表示“中文字符处理”状态, WORD 表示“英文字符处理”状态, LIN 表示“行符处理”状态, BOUND 表示“分界符处理”状态, PREPRO (预处理)就是“状态转换中心”。
字符统计程序如下:
file.get(ch);
SticState state=PREPRO;
while(1) {
switch(state) {
case CHN:
do {
if(ch!=中文字符 ) break;
chnum++;
} while(file.get(ch));
state=PREPRO;
break;
case WORD:
do {
if(ch!=英文字符 ) break;
engnum++;
} while(file.get(ch));
wordnum++;
state=PREPRO;
break;
case LIN:
do {
if(ch!=行符 ) break;
linenum++;
} while(file.get(ch));
state=PREPRO;
break;
case BOUND:
do {
if( ch!=分界符) break;
boundnum++;
} while(file.get(ch));
state=PREPRO;
break;
case PREPRO:
if(到文件尾) {
if(当前非行符) linenum++;// 对文件结尾的处理,可能会有最后一行没有回车的情况
return;
}
else if(ch=分界符) state=BOUND;
else if(ch=英文字符) state=WORD;
else if(ch=中文字符) state=CHN;
else if(ch=行符) state=LIN;
break;
default:
cout<<"未知状态错误 !"<<endl;
break;
}
}
4、 总结
本程序采用状态机的思想完成了设计要求,虽然不尽完美,但是我们也能从中学到如何用状态机的思想来比较轻松的完成程序设计。从本例可以看出,通过状态机的思想可以使程序变得简单、清晰、明了。所以,我们应该充分利用好这一有利的工具为我们的程序设计增添光彩!
源码下载地址:http://download.csdn.net/source/1797902
另附状态机学习的文章一篇:
系统程序员成长计划-文本处理(INI解析器)
http://blog.csdn.net/absurd/archive/2009/06/10/4255701.aspx
- 大小: 40.3 KB
分享到:
相关推荐
而一篇文本文件中出现的字符种类和顺序没有规律,如何对当前读取的字符的种类进行判断并转入到相应的统计状态成为了问题的关键。 但是,我们知道对于英文字母其ASCII码范围在65~90和97~122两个区间,而英文单词的...
通过阅读和理解这个文件,我们可以学习到词法分析器的具体实现细节,包括如何设置状态机,如何处理不同字符,以及如何构建和输出标记。这是一个很好的实践案例,可以帮助我们深入理解编译原理和C++的文件处理能力。
### 实验一 词法分析程序设计与实现 #### 实验背景与目的 词法分析是编译原理中的一个重要组成部分,其主要任务是从源代码中提取出一个个具有独立意义的基本单位(即“单词”),并将这些单词转换为特定的种别码...
了解词法分析程序设计步骤对于深入理解编译器工作原理至关重要。 词法分析程序设计通常包括以下步骤: 1. **输入准备**:程序首先读取源代码文件,并将其转化为字符流。这是通过创建一个缓冲区来完成的,用于存储...
状态机是词法分析器的核心,它维护了一组内部状态,并根据输入字符序列来改变状态,当达到特定状态时,就识别出了一个记号。 实现词法分析器时,需要考虑以下几点: 1. **关键词与保留字**:这些是语言中预定义的...
### 使用自动转换状态机实现的XML解析程序 #### 概述 本文介绍了一种使用状态机来解析XML文件的方法。状态机是一种广泛应用于各种场景下的有限状态自动机,它可以非常高效地处理各种输入序列,特别是在解析语言或者...
根据给定文件的信息,本文将围绕“使用状态机去除C语言程序中的注释”这一主题进行深入探讨。本文首先会介绍状态机的基本概念及其在去除注释中的应用,随后通过分析给定代码来理解其实现原理及过程。 ### 状态机的...
词法分析是编译器设计中的...通过阅读源代码,我们可以学习到如何用JAVA实现词法分析器,掌握状态机的设计,以及如何处理源代码中的各种元素。使用说明文档和状态图则进一步帮助我们理解程序的工作方式,提升学习效果。
这可能包括一个状态机模型,其中每个状态代表了词法分析的某个阶段,而状态之间的转移则根据输入字符进行。通过这样的模型,词法分析器可以逐步读取源代码,根据字符流改变其状态,直到识别出一个完整的词素。 在可...
词法分析器通常由正则表达式和状态机来定义,用于匹配输入源代码中的字符序列。 1. **词法分析器的工作原理**: - 词法分析器读取源代码的字符流,按照预定的规则(通常是正则表达式)进行匹配。 - 它将连续的...
本项目是一个用C++实现的SNL(特定于任务的非正规语言)词法分析程序,旨在对SNL语言的源代码进行词法解析。 词法分析通常涉及以下步骤: 1. **扫描源代码**:程序会逐字符地读取源代码,忽略空格、注释等非重要...
词法分析器,也称为扫描器或词法分析...在这个实验中,你可以学习到如何使用C语言来处理文本,如何设计和实现状态机,以及如何调试和优化词法分析器。这样的实践对于理解编译器的工作原理和提高编程技能都非常有益。
在实验中,`cbb.cpp`可能包含了这样的状态机逻辑,用于读取源代码文件的每一行,逐个字符地进行分析,将识别出的词法单元存储在一个数据结构中,如链表或向量。这些词法单元随后可以作为输入传递给语法分析器进行...
本课件详细介绍了C语言中的文件操作,对于学习者深入理解C语言程序设计,尤其是涉及到文件处理的场景,具有极高的参考价值。通过学习,开发者能够编写出能处理各种类型文件,实现高效读写的C程序。
词法分析程序是编译器设计中的重要组成部分,它负责将源代码文本转换为一系列有意义的符号或标记,这些标记随后被语法分析器用来构建抽象语法树,最终生成目标代码。在C++编程环境中,我们可以使用各种技术来实现...
【C程序设计中的文件操作】 在C语言编程中,文件操作是至关重要的,尤其是在处理大量数据或者需要持久化存储信息时。谭浩强的C程序设计课件详细讲解了文件操作的相关知识,主要包括以下几个方面: 1. **文件的基本...
1. **输入处理**:程序首先读取源代码文件,将其内容转化为字符数组或者使用缓冲流进行处理。 2. **状态机**:这个词法分析器可能使用有限状态自动机(FSM)来识别不同的词法模式。每个状态代表了词法分析的一个阶段...