-1

入力からコメントと文字列を削除することを想定している次のコードの何が問題なのか、誰か教えてもらえますか? これは私の以前の質問に関連しています:ネストされた while ループのないスライディング ウィンドウでコメントを削除する

#include <stdio.h>

int main()
{
    int c, c1 = 0, c2 = 0 ,state = 0, next = 0;
    while(1)
    {
        switch(state)
        {
           case 0: next = ((c2 == '*' && c1 == '/') ? 1 : (c2 == '\"') ? 2 : (c2 == '/' && c1 == '/') ? 3 : (c2 == '\'') ? 4: 0); break; 
           case 1: next = ((c2 == '/' && c1 == '*') ? 0 : 1); break; 
           case 2: next = ((c2 == '\"' && c1 != '\\') ? 0 : 2); break;
           case 3: next = ((c2 == '\n') ? 0 : 3); break;
           case 4: next = ((c2 == '\'' && c1 != '\\') ? 0 : 4); break;
           default: next = state; 
        }
        c = getchar(); if( c < 0) break;
        c1 = c2; c2 = c; // slide window
        if(state == 1)
        {
            if(c2 == '*')
            {
                c = getchar();
                c1 = c2; c2 = c;
                if(c2 != '/')
                   putchar(c1);
            }
            else
                putchar(c2);
        }
        else if(state == 2)
        {
            if(c2 != '"' || (c2 == '\"' && c1 != '\\'))
                putchar(c2);
        }
        else if(state == 3)
        {
                putchar(c2);
        }
        else
        state = next;
        // c2 is the current input byte and c1 is the previous input byte
    }
    return 0;
}
4

2 に答える 2

1

C および C++ のコメントを削除するタスクにスライディング ウィンドウが実際に必要だとは思いません。ステート マシンを拡張して、エスケープなどを追跡するためのいくつかの追加状態を含めることができます。状態が増えると、コードが少し大きくなりますが、追跡する状態が1 つしかないため、概念的には単純になる可能性があります。したがって、コードの精神を私が提案する新しいステート マシンの式に変換すると、以下のコードが得られます (列挙型を使用するという Basile の提案にも同意し、それを含めました)。

#include <stdio.h>

int main()
{
    enum {
        START, SLASH,
        STRING, CHAR, STRING_ESCAPE, CHAR_ESCAPE,
        SINGLE_LINE_COMMENT, MULTI_LINE_COMMENT, MULTI_LINE_END,
    } state = START;
    int c;

    while ((c = getchar()) != EOF) {
        switch (state) {
        case START:
        state_START:
            if (c == '/') { state = SLASH; break; }
            putchar(c);
            if (c == '\"') state = STRING;
            else if (c == '\'') state = CHAR;
            break;
        case SLASH:
            if (c == '/') state = SINGLE_LINE_COMMENT;
            else if (c == '*') state = MULTI_LINE_COMMENT;
            else { state = START; goto state_START; }
            break;
        case STRING:
            putchar(c);
            if (c == '"') state = START;
            else if (c == '\\') state = STRING_ESCAPE;
            break;
        case CHAR:
            putchar(c);
            if (c == '\'') state = START;
            else if (c == '\\') state = CHAR_ESCAPE;
            break;
        case SINGLE_LINE_COMMENT:
            if (c == '\n') state = START;
            break;
        case MULTI_LINE_COMMENT:
        state_MULTI_LINE_COMMENT:
            if (c == '*') state = MULTI_LINE_END;
            break;
        case STRING_ESCAPE:
            putchar(c);
            state = STRING;
            break;
        case CHAR_ESCAPE:
            putchar(c);
            state = CHAR;
            break;
        case MULTI_LINE_END:
            if (c == '/') state = START;
            else { state = MULTI_LINE_COMMENT; goto state_MULTI_LINE_COMMENT; }
            break;
        }
    }
    return 0;
}
于 2013-04-19T16:58:08.343 に答える
0

目的を知らずにアドバイスをするだけです...問題を解決するために正規表現について考えましたか? 正規表現を理解していると仮定すると、より速く、コードがよりきれいになります。

ところで、あなたの問題に関するきちんとしたサイトを見つけました...コードからそれらのコメントを取得する方法を説明しています...

正規表現でコメントを取得する方法

そして、ここにCの正規表現用のライブラリがあります.

于 2013-04-19T13:05:02.550 に答える