Игнорировать комментарии из строки, прочитанной с помощью strstr в C

#c #comments #strstr

#c #Комментарии #strstr

Вопрос:

Я должен написать код без сторонних библиотек, которые читают из файла строка за строкой, и искать оператор переключения или регистра. Пока мой код для этого таков:

 while(fgets(st, 1001, f1))
{
    lineCnt  ;
    if(strstr(st, "switch"))
    {
        if(!strstr(st, """))
              switchCnt  ;
    }
    if(strstr(st, "case"))
    {
        if(!strstr(st, """))
        caseCnt  ;
    }
}
 

Который в основном проверяет, есть ли в данной строке кавычка, и если есть, не увеличивайте количество переключений. Я думаю, что это охватывает большинство случаев, поскольку я не думаю, что в строке с фактическим оператором switch будет кавычка, но я открыт для идей и по этой части. Я сделал то же самое и для счетчика обращений.

Как игнорировать части комментариев при чтении файла, поскольку, если есть, скажем //switch count , это будет учтено?

Комментарии:

1. Если вы хотите сделать это идеально, вам в основном нужно написать синтаксический анализатор C

2. Разве ваш код не работает?

3. Прочитайте первую половину книги Dragon . Рассмотрите возможность использования flex с GNU bison или прочитайте хотя бы википедию о синтаксическом анализе и анализаторах с рекурсивным спуском . Изучите для вдохновения исходный код nwcc

Ответ №1:

Ответить на этот вопрос сложнее, чем вы думаете. «Правильное» решение — написать полный синтаксический анализатор C, что довольно сложно.

Чтобы сделать это хорошо, вам нужна лучшая спецификация. Но я думаю, мы можем предположить, что вы не допустите подобных вещей:

 #define switch haha
#define foobar case
 

И когда дело доходит до комментариев. Помните, что у вас есть два типа комментариев. // и /* */ . Кроме того, вам также необходимо иметь дело со строковыми литералами и многосимвольными литералами. Вот фрагмент с некоторыми хитрыми причудами, чтобы дать представление о том, о чем вы на самом деле спрашиваете:

 /* switch program
int main(void)
// */
#include <stdio.h>

int main(void) {
    char *str = "switch" // /*";
    /* char *str = "*/"switch";
    printf("//");
    switch((long)"case") /* { */ { /*
        case 1 : 
    */  case 1 : break;
    }

    int c = '"//"'; // Multi character constant which is including
                   // Both comment and quote character
    // This is a comment 
    and so is this
}
    
 

Обратите внимание, что приведенный выше код не имеет смысла, но он компилируется.

Ответ №2:

Чтобы вырезать комментарии, вырежьте комментарии.

Если вы просто хотите вырезать все после // , это будет:

 while(fgets(st, 1001, f1))
{
    char* comment = strstr(st, "//");
    if (comment != NULL) *comment = '';
 

Обратите внимание, что это сокращение также будет применено, например, "hoge///";switch .
(Я не знаю синтаксиса файла, с которым нужно иметь дело, поэтому я не могу сказать, нормально ли это поведение или нет)

Комментарии:

1. Я попробую это. Файл, с которым нужно работать, является программой .c.