C++抽象编程——面向对象(10)——token扫描器的实现

来源:互联网 发布:淘宝上钻石多少好评 编辑:程序博客网 时间:2024/06/06 09:15

tokenscanner.h接口

界面中的许多方法用于启用更改扫描仪默认行为的选项。例如,我们可以通过初始化像这样的token扫描器忽略输入流中的所有空格:

TokenScanner scanner;scanner.ignoreWhitespace();

接下来我们的目的是实现下面的一些功能:

方法 作用 构造函数 TokenScanner() TokenScanner(str) TokenScanner(infile) 初始化扫描仪对象。 token的源码从指定的字符串或输入文件初始化。如果没有提供token源,则必须在从扫描仪读取令牌之前调用setInput 读取token的方法 hasMoreTokens() 返回true,如果还有其他更多的token未被读取 nextToken() 从扫描仪返回下一个token。 如果在没有token可用的情况下调用nextToken,则返回空字符串。 saveToken(token) 将指定的token保存为扫描仪内部状态的一部分,以便在下次调用nextToken时返回。 控制扫描器的方法 ignoreWhitespace() 告诉扫描仪扫描的时候忽略空格字符

实现简单的token扫描器

TokenScanner.h

#ifndef _TokenScanner_h#define _TokenScanner_h#include <string>/**这个类用来处理一些分割字符串*/class TokenScanner{    public:        /*        *构造函数: TokenScanner scanner        *用法:TokenScanner scanner()               TokenScanner scanner(str)        *---------------------------        *用途:创建一个TokenScanner对象,当其为默认构造函数的时候        *token为空字符串,否则,这token来自于用户定义的字符串        */         TokenScanner();        TokenScanner(std::string str);         /*        *方法:setInput()        *用法:scanner.setInput(str)        *--------------------------        *用途:为扫描器提供指定的string输入        */        void setInput(std::string str);         /*        *方法:hasMoreTokens        *用法:if(scanner.hasMoreTokens)        *------------------------------        *用途:判断是否还有后续的tokens        */        bool hasMoreTokens();        /*        *方法:nextToken        *用法:token = scanner.nextToken()        *--------------------------------        *用途:返回下一个token的值。如果没有后续的token,那么返回空字符串        */        std::string nextToken();        /*        *方法:ignoreWhitespace        *用法:scanner.ignoreWhitespace()        *-----------------------------        *用途:告诉扫描仪忽略空格字符。 默认情况下,nextToken方法像任何其        *它标点符号一样处理空格字符(通常为空格和制tab),并将其作为单字符        *token返回。调用:        * scanner.ignoreWhitespace();        *以便我们可以这样操作        */        void ignoreWhitespace();        #include "tokenscannerpriv.h"}; #endif

TokenScannerpriv.h

/**这个文件为TokenScanner类的私有部分*/private:    /*实例化变量*/    std::string buffer; //包含token的输入字符串,buffer的意思为缓存    int cp; //token在缓存中的正确位置,cp:current position     bool ignoreWhitespaceFlag;//设立一个忽略空格的标志,注意这是一个变量    /*私有方法*/    void skipWhitespace(); //跳过空格 

TokenScanner.cpp

/**这个文件用于实现我们前面写的TokenScanner的功能*/#include <cctype>#include <string>#include "TokenScanner.h"using namespace std;/*构造函数的实现*/TokenScanner::TokenScanner(){    /*空函数*/ } TokenScanner::TokenScanner(string str){    setInput(str);}/*setInput函数的实现*/void TokenScanner::setInput(string str){    buffer = str;    cp = 0;} /**hasMoreTokens函数的实现*当cp在buffer的里面的时候,意味着分割尚未完成,所以返回true*当遇到空格时候,就跳过空格*/ bool TokenScanner::hasMoreTokens() {    if (ignoreWhitespaceFlag) skipWhitespace();    return cp < buffer.length();}/**nextToken函数的实现*该方法通过查看由cp指示的当前字符处的字符开始。 *如果该位置超过了字符串的结尾,则nextToken将返回空字符串。 *如果该字符是字母数字,则nextToken会继续向前扫描,直到找到该字的结尾; *如果没有,则nextToken将该字符作为单字符字符串返回 */string TokenScanner::nextToken() {    if (ignoreWhitespaceFlag) skipWhitespace();    if (cp >= buffer.length()) {        return "";        } else if (isalnum(buffer[cp])) {//判断是否为字母数字             int start = cp; //将此时开始的cp的位置赋给start            /*当cp处于buffer内,且cp中所指的都是字母数字的时候*/             while (cp < buffer.length() && isalnum(buffer[cp])) {                cp++;            }        return buffer.substr(start, cp - start);//返回截取的这一段字符         } else {            return string(1, buffer[cp++]);    }} /*ignoreWhitespace()函数的实现 */void TokenScanner::ignoreWhitespace() {    ignoreWhitespaceFlag = true;} /**此方法是一种私有方法,因此不会导出。 *但是,它需要在类的私有部分中声明,该部分*包含在tokenscannerpriv.h文件中。 *这个方法从hasMoreTokens和nextToken都调用*/void TokenScanner::skipWhitespace() {    while (cp < buffer.length() && isspace(buffer[cp])) {    cp++;    }}

测试文件

#include <iostream>#include <string>#include "TokenScanner.h"using namespace std;int main(){    string line;    getline(cin,line);    TokenScanner scanner(line);    for(int i = 0;i <= line.length();i++){        string str =  scanner.nextToken();        cout << str << endl;    }    return 0;} 

测试结果

自此,面向对象暂时告一段落,以后会提到虚函数之类的

1 0
原创粉丝点击