使用c ++计算多行注释之间的所有行

时间:2015-11-01 22:02:43

标签: c++ file parsing

我正在创建一个程序,我可以用任何语言计算每个编程项目的注释,但是当我想计算这样的多行注释时,我在行计数方面存在问题:

/* this is 
  a multiline
  comment */

或Ruby方式:

=begin 
this is multiline
comment
=end

我无法想出一种计算多行评论中每一行的方法 这是我的一段代码:

while(getline(file_f,line)) {

    lines_count++;

    if((line.empty()))
        blanklines_count++;

    if(((line.find("//")) != string::npos) || (line.find("/*") != string::npos)) 
        comments++;

我没有在其他帖子中找到关于我的getline实现问题的有用的东西,有什么解决方案吗?

4 个答案:

答案 0 :(得分:2)

< p>您需要设置一些< code> bool< / code>标志变量,将设置为< code> true< / code>输入评论时,设置为< code> false< / code>当你离开时。< / p> < pre>< code> //将std :: string :: find短路更好 //(如果您已经在一个评论中,请不要查找多行注释的开头) if(!inComment&& line.find(" // *")!= std :: string :: npos)     inComment = true; //不要在这里增加,只需设置标志 if(inComment || line.find(" //"))!= std :: string :: npos)     意见++; if(inComment&& line.find(" * //")!= std :: string :: npos)     inComment = false; < /代码>< /预>

答案 1 :(得分:2)

您希望在多行评论中标记,例如:

bool in_multi_line_comment = false;

// ...

while//...

    // ...
    if (!in_multi_line_comment && line.find("/*") != string::npos)
        in_multi_line_comment = true;

    if (in_multi_line_comment || line.find("//")) != std::string::npos)
        comments++;

    if (in_multi_line_comment && line.find("*/") != string::npos)
        in_multi_line_comment = false;

答案 2 :(得分:2)

您需要一个布尔变量来告诉您是否在多行注释中。让我们称之为is_inside_mcomment

  • 当您找到多行评论标记时(例如“/ *”)

    is_inside_comment = true
    
  • 找到多行注释结束标记(例如'* /')

    is_inside_comment = true
    
每行

  • if is_inside_mcomment comments++

根据您希望程序的复杂性和准确性,您必须考虑特殊情况:(例如,同一行上的多个多行注释,字符串内的标记等)

答案 3 :(得分:2)

你需要一个实际有状态并且知道输入的解析器。

  

例如您不想将/*解析为c ++中的块注释的开头,如果它出现在此处:

std::cout << "Hello /*interesting*/ world!\n";

除此之外,这里有一个快速演示,使用Boost Spirit为您在问题中概述的任务滚动最小解析器:

<强> Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>
#include <limits>

namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;
namespace px = boost::phoenix;

int main(int argc, char** argv) {
    std::vector<std::string> args(argv+1, argv+argc);
    if (args.empty())
        args.push_back("cpp");

    size_t comment_lines = 0;
    auto incr = px::ref(comment_lines)++;

    using It = boost::spirit::istream_iterator;
    qi::rule<It> rule;
    {
        using namespace qi;
        if (args.front() == "cpp")
            rule = qr::seek["/*"] >> ((*(char_ - eol - "*/")) [incr] % eol);
        else if (args.front() == "ruby")
            rule = qr::seek["\n=begin"] >> *(char_ - eol) % (eol - (eol >> "=end")) [incr];
        else
            rule = eps(false); // just fail
    }

    if (qi::parse(It(std::cin >> std::noskipws), {}, rule)) {
        std::cout << comment_lines << " lines in " << args.front() << " comments\n";
    } else {
        std::cout << "Couldn't parse " << args.front() << " input\n";
    }
}

使用

运行示例输入时
for lang in cpp ruby java; do ./a.out $lang input.txt; done

您将获得输出:

3 lines in cpp comments
2 lines in ruby comments
Couldn't parse java input