Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从字符串中删除行注释_C++_String_C++11 - Fatal编程技术网

C++ 从字符串中删除行注释

C++ 从字符串中删除行注释,c++,string,c++11,C++,String,C++11,我正在编写一个文本解析器,它需要能够从行中删除注释。我使用的是一种相当简单的语言,其中所有注释都由#字符启动,删除之后的所有内容都很简单,但我必须处理#位于字符串内部的可能性 因此,我的问题是,给定一个字符串,如 Value=“字符串#1”;“字符串2”;#这是一个由“-分隔的字符串组成的数组,如“ 如何最好地提取子字符串 Value=“String#1”;“String#2”(注意尾随空格) 请注意,注释可能包含引号,并且整行可以在“删除”和“删除”之间进行选择,尽管它在整行上是一致的。这是事

我正在编写一个文本解析器,它需要能够从行中删除注释。我使用的是一种相当简单的语言,其中所有注释都由#字符启动,删除之后的所有内容都很简单,但我必须处理#位于字符串内部的可能性

因此,我的问题是,给定一个字符串,如
Value=“字符串#1”;“字符串2”;#这是一个由“-分隔的字符串组成的数组,如“

如何最好地提取子字符串
Value=“String#1”;“String#2”
(注意尾随空格)

请注意,注释可能包含引号,并且整行可以在“删除”和“删除”之间进行选择,尽管它在整行上是一致的。这是事先知道的,如果它是重要的。字符串中的引号将由\

std::string stripComment(std::string str) {
    bool escaped = false;
    bool inSingleQuote = false;
    bool inDoubleQuote = false;
    for(std::string::const_iterator it = str.begin(); it != str.end(); it++) {
         if(escaped) {
             escaped = false;
         } else if(*it == '\\' && (inSingleQuote || inDoubleQuote)) {
             escaped = true;
         } else if(inSingleQuote) {
             if(*it == '\'') {
                 inSingleQuote = false;
             }
         } else if(inDoubleQuote) {
             if(*it == '"') {
                 inDoubleQuote = false;
             }
         } else if(*it == '\'') {
             inSingleQuote = true;
         } else if(*it == '"') {
             inDoubleQuote = true;
         } else if(*it == '#') {
             return std::string(str.begin(), it);
         }
    }
    return str;
}
编辑:或更教科书式的FSM

std::string stripComment(std::string str) {
    int states[5][4] = {
    //      \  '  "
        {0, 0, 1, 2,}
        {1, 3, 0, 1,},  //single quoted string
        {2, 4, 2, 0,},  //double quoted string
        {1, 1, 1, 1,},  //escape in single quoted string
        {2, 2, 2, 2,},  //escape in double quoted string
    };
    int state = 0;
    for(std::string::const_iterator it = str.begin(); it != str.end(); it++) {
        switch(*it) {
            case '\\':
                state = states[state][1];
                break;
            case '\'':
                state = states[state][2];
                break;
            case '"':
                state = states[state][3];
                break;
            case '#':
                if(!state) {
                    return std::string(str.begin(), it);
                }
            default:
                state = states[state][0];
        }          
    }
    return str;
}
状态
数组定义FSM状态之间的转换

第一个索引是当前状态,
0
1
2
3
4

第二个索引对应于字符,
\
'
,或其他字符

该数组根据当前状态和角色告知下一个状态


仅供参考,这些假设是反斜杠转义字符串中的任何字符。你至少需要它们转义反斜杠,这样你就可以有一个以反斜杠结尾的字符串。

你没有处理内部引号。请放慢速度,在发布之前立即获得它。我正要对你的答案进行否决。现在你有足够的理由将其作为
switch
block。会更容易阅读。
&&!inSingleQuote&&!inDoubleQuote
是多余的。另外:由于您编写了一个FSM,您可以去掉所有标志并使用一个枚举变量。这个星球上的每个lexer生成器都提供了一些示例,说明如何处理注释。您尝试过使用一个吗?您尝试过吗把词法分析阶段完全分开?