• 去注释程序


    去注释程序

             C/C++中注释有两种形式:

             1./* … */

             2.// …

             我们要实现的功能就是讲程序中的注释过滤掉。

             我们首先采用一种直接的方法进行过滤,就是顺序扫描整个源代码,检测 /*、*/、// 这些标示,以获取程序的注释。

    // 程序1:顺序扫描
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <vector>
    using namespace std;
    
    void read_prog(const string& file, string& prog)
    {
        ifstream fin(file.c_str());
        if (!fin)
        {
            cerr << file << " error!" << endl;
            exit(2);
        }
        prog.clear();
        string line;
        while (getline(fin, line))
        {
            prog += line + '
    ';
        }
    }
    
    void filter(const string& prog, string& prog_filtered, vector<string>& comments)
    {
        prog_filtered.clear();
        comments.clear();
    
        char ch = 0;
    
        for (string::size_type i = 0; i < prog.size(); )
        {
            string tmp;
            ch = prog[i];
            if (ch == '/')
            {
                tmp += ch;
                ++i;
                if (i >= prog.size())
                {
                    prog_filtered += tmp;
                    return;
                }
                ch = prog[i];
                if (ch == '*')
                {
                    tmp += ch;
                    ++i;
                    string::size_type pos = prog.find("*/", i);
                    if (pos < prog.size())
                    {
                        tmp += prog.substr(i, pos - i + 2);
                        i = pos + 2;
                        comments.push_back(tmp);
                    }
                    else
                    {
                        tmp += prog.substr(i);
                        i = prog.size();
                        prog_filtered += tmp;
                    }
                }
                else if (ch == '/')
                {
                    tmp += ch;
                    ++i;
                    string::size_type pos = prog.find('
    ', i);
                    tmp += prog.substr(i, pos - i);
                    i = pos;
                    comments.push_back(tmp);
                }
                else
                {
                    tmp += ch;
                    ++i;
                    prog_filtered += tmp;
                    tmp.clear();
                }
            }
            else
            {
                tmp += ch;
                ++i;
                prog_filtered += tmp;
                tmp.clear();
            }
        }
    }
    
    int main()
    {
        string prog, prog_filtered;
        vector<string> comments;
    
        read_prog("prog.txt", prog);
        cout << prog << endl;
        filter(prog, prog_filtered, comments);
    
        cout << prog_filtered << endl;
        for (vector<string>::size_type i = 0; i != comments.size(); ++i)
        {
            cout << i + 1 << ':' << comments[i] << endl;
        }
        return 0;
    }

    测试样例:

    #include <iostream>
    using namespace std;
    
    /// test1
    //* test2*/
    // main函数
    int main()
    {
        /* 主函数 */
        /*
         *注释
             */
    }
    // 阿萨德发生的发生地方
    /* asdfasdf *

             做法2:利用状态转换图

     

    // 程序2:利用状态转换图进行注释的过滤
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <vector>
    using namespace std;
    
    void read_prog(const string& file, string& prog)
    {
        ifstream fin(file.c_str());
        if (!fin)
        {
            cerr << file << " error!" << endl;
            exit(2);
        }
        prog.clear();
        string line;
        while (getline(fin, line))
        {
            prog += line + '
    ';
        }
    }
    
    void StateTransitionDiagram(const string& prog, string& prog_filtered, vector<string>& comments)
    {
        int state = 1;
        string tmp;
        for (string::size_type i = 0; i < prog.size(); ++i)
        {
            char ch = prog[i];
            switch (state)
            {
            case 1:
                if (ch == '/')
                {
                    tmp += ch;
                    state = 2;
                }
                else
                {
                    prog_filtered += ch;
                }
                break;
    
            case 2:
                if (ch == '*')
                {
                    tmp += ch;
                    state = 3;
                }
                else if (ch == '/')
                {
                    tmp += ch;
                    state = 5;
                }
                else
                {
                    tmp += ch;
                    prog_filtered += tmp;
                    tmp.clear();
                    state = 1;
                }
                break;
    
            case 3:
                if (ch == '*')
                {
                    tmp += ch;
                    state = 4;
                }
                else
                {
                    tmp += ch;
                }
                break;
    
            case 4:
                if (ch == '/')
                {
                    tmp += ch;
                    comments.push_back(tmp);
                    tmp.clear();
                    state = 1;
                }
                else
                {
                    tmp += ch;
                    state = 3;
                }
                break;
    
            case 5:
                if (ch == '
    ')
                {
                    comments.push_back(tmp);
                    tmp.clear();
                    state = 1;
                    --i;
                }
                else
                {
                    tmp += ch;
                }
                break;
    
            default:
                cerr << "Error!" << endl;
                break;
            }
        }
    }
    
    int main()
    {
        string prog, prog_filtered;
        vector<string> comments;
    
        read_prog("prog.txt", prog);
        cout << prog << endl;
        StateTransitionDiagram(prog, prog_filtered, comments);
    
        cout << prog_filtered << endl;
        for (vector<string>::size_type i = 0; i != comments.size(); ++i)
        {
            cout << i + 1 << ':' << comments[i] << endl;
        }
        return 0;
    }

    测试样例:

    #include <iostream>
    using namespace std;
    
    /// test1
    //* test2*/
    // main函数
    int main()
    {
        /* 主函数 */
        /*
         *注释
             */
    }
    // 阿萨德发生的发生地方
    /* asdfasdf *

             总结

             上文利用两种方法进行两种注释的过滤,第一种方式是顺序扫描程序,当检测到/、*等字符时进行检测判断,对符合条件的注释进行提取。

             第二种方法是借助了状态转换图,设置扫描程序中根据不同字符设置当前状态值state,根据当前状态state以及当前字符进行判断,对符合条件的注释进行提取过滤。

             第一种方法是仅仅利用了当前字符的特性,在当前字符条件下进行后续的处理。第二种方法除了利用当前字符的特性外,还结合了检测的状态,这样记录的信息更多,使得程序处理逻辑更为简单清晰,更有利于逻辑的划分和程序的书写,同时也提高了代码的可读性。

             第一种方法是if的嵌套,多层if。第二种方法利用了switch-case语句(也可以是if语句)使得处理逻辑得以平铺,整个处理流程更为清晰易懂。这可能就是状态转换图的优点之所在。

             数据结构决定算法,增加信息表示方法和途径,使得信息处理更为简单易行。预处理的思想也就在于增加信息表达方式,使得后续处理更为快捷和方便。

  • 相关阅读:
    PHP引用与global操作符
    php关联数组与索引数组及其显示
    vim列模式
    PHP 魔术方法之__set() __get() 方法
    给图片、表格、公式自编号
    如何将本地项目与coding.net/github上的项目绑定
    用 ElementTree 在 Python 中解析 XML
    用 ElementTree 在 Python 中解析 XML
    正则表达式介绍
    一个javascript面试题解析
  • 原文地址:https://www.cnblogs.com/unixfy/p/3255016.html
Copyright © 2020-2023  润新知