Удалите комментарии из кода C/C++

Есть ли простой способ удалить комментарии из исходного файла C/C++, не делая никакой предварительной обработки. (т.е., я думаю, что можно использовать gcc-E, но это развернет макросы.) Я просто хочу исходный код с разделенными комментариями, ничто иное не должно быть изменено.

Править:

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

66
задан Mike 6 March 2010 в 20:36
поделиться

3 ответа

Выполните следующую команду в исходном файле:

gcc -fpreprocessed -dD -E test.c

Спасибо Kenny TM за обнаружение правильные флаги. Вот результат для полноты:

test.c:

#define foo bar
foo foo foo
#ifdef foo
#undef foo
#define foo baz
#endif
foo foo
/* comments? comments. */
// c++ style comments

gcc -fpreprocessed -dD -E test.c :

#define foo bar
foo foo foo
#ifdef foo
#undef foo
#define foo baz
#endif
foo foo
97
ответ дан 24 November 2019 в 14:58
поделиться

gcc -fpreprocessed -dD -E у меня не работал, но эта программа делает это:

#include <stdio.h>

static void process(FILE *f)
{
 int c;
 while ( (c=getc(f)) != EOF )
 {
  if (c=='\'' || c=='"')            /* literal */
  {
   int q=c;
   do
   {
    putchar(c);
    if (c=='\\') putchar(getc(f));
    c=getc(f);
   } while (c!=q);
   putchar(c);
  }
  else if (c=='/')              /* opening comment ? */
  {
   c=getc(f);
   if (c!='*')                  /* no, recover */
   {
    putchar('/');
    ungetc(c,f);
   }
   else
   {
    int p;
    putchar(' ');               /* replace comment with space */
    do
    {
     p=c;
     c=getc(f);
    } while (c!='/' || p!='*');
   }
  }
  else
  {
   putchar(c);
  }
 }
}

int main(int argc, char *argv[])
{
 process(stdin);
 return 0;
}
7
ответ дан 24 November 2019 в 14:58
поделиться

Это зависит от того, насколько извращены ваши комментарии. У меня есть программа scc для удаления комментариев C и C ++. У меня также есть тестовый файл для него, и я попробовал GCC (4.2.1 в MacOS X) с параметрами в текущем выбранном ответе - и GCC, похоже, не идеально справляется с некоторыми из ужасно убитых комментариев в прецедент.

NB: Это не реальная проблема - люди не пишут такой ужасный код.

Рассмотрим (подмножество - 36 из 135 строк) тестового примера:

/\
*\
Regular
comment
*\
/
The regular C comment number 1 has finished.

/\
\/ This is not a C++/C99 comment!

This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.

/\
\* This is not a C or C++ comment!

This is followed by regular C comment number 2.
/\
*/ This is a regular C comment *\
but this is just a routine continuation *\
and that was not the end either - but this is *\
\
/
The regular C comment number 2 has finished.

This is followed by regular C comment number 3.
/\
\
\
\
* C comment */

На моем Mac вывод GCC ( gcc -fpreprocessed -dD -E subset.c ):

/\
*\
Regular
comment
*\
/
The regular C comment number 1 has finished.

/\
\/ This is not a C++/C99 comment!

This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.

/\
\* This is not a C or C++ comment!

This is followed by regular C comment number 2.
/\
*/ This is a regular C comment *\
but this is just a routine continuation *\
and that was not the end either - but this is *\
\
/
The regular C comment number 2 has finished.

This is followed by regular C comment number 3.
/\
\
\
\
* C comment */

Результатом 'scc' является:

The regular C comment number 1 has finished.

/\
\/ This is not a C++/C99 comment!

This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.

/\
\* This is not a C or C++ comment!

This is followed by regular C comment number 2.

The regular C comment number 2 has finished.

This is followed by regular C comment number 3.

Результатом 'scc -C' (который распознает комментарии с двойным слэшем) является:

The regular C comment number 1 has finished.

/\
\/ This is not a C++/C99 comment!

This is followed by C++/C99 comment number 3.

The C++/C99 comment number 3 has finished.

/\
\* This is not a C or C++ comment!

This is followed by regular C comment number 2.

The regular C comment number 2 has finished.

This is followed by regular C comment number 3.

Исходный код для SCC теперь доступен на GitHub

Текущая версия SCC - 6.60 (от 12 июня 2016 г.), хотя версии Git были созданы 18 января 2017 г. (в часовом поясе США и Тихого океана). Код доступен на GitHub по адресу https://github.com/jleffler/scc-snapshots . Вы также можете найти снимки предыдущих выпусков (4.03, 4.04, 5.05) и двух предварительных выпусков (6.16, 6.50) - все они имеют теги release / x.yz .

Код все еще в основном разрабатывается в рамках RCS. Я все еще работаю над тем, как использовать подмодули или аналогичный механизм для обработки общих файлов библиотеки, таких как stderr.c и stderr.h (которые также можно найти в https://github.com/jleffler/soq ).

SCC версии 6.60 пытается понять конструкции C ++ 11, C ++ 14 и C ++ 17, такие как двоичные константы, числовые знаки препинания, необработанные строки и шестнадцатеричные числа с плавающей запятой. По умолчанию он работает в режиме C11.(Обратите внимание, что значение флага -C , о котором говорилось выше, менялось между версией 4.0x, описанной в основной части ответа, и версией 6.60, которая на данный момент является последней версией.)

{{1 }}
15
ответ дан 24 November 2019 в 14:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: