Есть ли простой способ удалить комментарии из исходного файла C/C++, не делая никакой предварительной обработки. (т.е., я думаю, что можно использовать gcc-E, но это развернет макросы.) Я просто хочу исходный код с разделенными комментариями, ничто иное не должно быть изменено.
Править:
Предпочтение к существующему инструменту. Я не хочу должным быть писать это сам с regexes, я предвижу слишком много неожиданностей в коде.
Выполните следующую команду в исходном файле:
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
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;
}
Это зависит от того, насколько извращены ваши комментарии. У меня есть программа scc
для удаления комментариев C и C ++. У меня также есть тестовый файл для него, и я попробовал GCC (4.2.1 в MacOS X) с параметрами в текущем выбранном ответе - и GCC, похоже, не идеально справляется с некоторыми из ужасно убитых комментариев в прецедент.
Рассмотрим (подмножество - 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 - 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, которая на данный момент является последней версией.)