Удаление комментариев из кода C / C++
есть ли простой способ удалить комментарии из исходного файла C/C++ без предварительной обработки. (т. е., я думаю, вы можете использовать gcc-E, но это расширит макросы.) Я просто хочу, чтобы исходный код с комментариями был удален, больше ничего не нужно менять.
EDIT:
предпочтение по отношению к существующему инструменту. Я не хочу писать это сам с помощью регулярных выражений, я предвижу слишком много сюрпризов в коде.
11 ответов:
выполните следующую команду в исходном файле:
gcc -fpreprocessed -dD -E test.cспасибо KennyTM за поиск правильных флагов. Вот результат для полноты картины:
это зависит от того, насколько извращенными являются ваши комментарии. У меня есть программа
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 подмножество.с):
/\ *\ 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 (датирована 2016-06-12), хотя версии Git были созданы в 2017-01-18 (в часовом поясе США/Тихого океана). Код доступен из 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.0 x, описанной в основном тексте ответа, и версией 6.60, которая в настоящее время является последней версией.)
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; }
есть stripcmt программа, чем может это сделать:
StripCmt-это простая утилита, написанная на языке C для удаления комментариев из исходных файлов C, C++ и Java. В великой традиции программ обработки текста Unix он может функционировать либо как фильтр FIFO (First In - First Out), либо принимать аргументы в командной строке.
(за hlovdal ' s ответ на: вопрос о коде Python для этого)
это скрипт perl для удаления / / однострочных и / * многострочных * / комментариев
#!/usr/bin/perl undef $/; $text = <>; $text =~ s/\/\/[^\n\r]*(\n\r)?//g; $text =~ s/\/\*+([^*]|\*(?!\/))*\*+\///g; print $text;требуется исходный файл в качестве аргумента командной строки. Сохраните скрипт в файл, скажем remove_comments.pl и вызовите его с помощью следующей команды: perl-w remove_comments.pl [ваш исходный файл]
надеюсь, что это будет полезным
У меня тоже была эта проблема. Я нашел этот инструмент (Cpp-Decomment) , который работал для меня. Однако он игнорирует, если строка комментария распространяется на следующую строку. Например:
// this is my comment \ comment continues ...в этом случае я не мог найти способ в программе, поэтому просто искал игнорируемые строки и исправлял вручную. Я считаю, что для этого есть вариант или, возможно, вы можете изменить исходный файл программы для этого.
Я считаю, что если вы используете один оператор, вы можете легко удалить комментарии из C
perl -i -pe ‘s/\\*(.*)/g’ file.c This command Use for removing * C style comments perl -i -pe 's/\\(.*)/g' file.cpp This command Use for removing \ C++ Style Commentsтолько проблема с этой командой он не может удалить комментарии, которые содержат более одной строки.но с помощью этого регулярного выражения вы можете легко реализовать логику для многострочного удаления комментариев
недавно я написал код Ruby, чтобы решить эту проблему. Я рассмотрел следующие исключения:
- комментарии в строки
- несколько строк комментарий на одной строке, исправить жадный матч.
- несколько строк в несколько строк
вот код:Github, удалить комментарии
Он использует следующий код для обработки каждой строки в случае, если эти комментарии отображаются в строках. Если он появится в вашем коде, ЭМ, плохо удача. Вы можете заменить его более сложными строками.
- MUL_REPLACE_LEFT ="MUL_REPLACE_LEFT"
- MUL_REPLACE_RIGHT ="MUL_REPLACE_RIGHT"
- SIG_REPLACE ="SIG_REPLACE"
использование: ruby-w inputfile outputfile
поскольку вы используете C, вы можете использовать что-то "естественное" для C. Вы можете использовать препроцессор C, чтобы просто удалить комментарии. Приведенные ниже примеры работают с препроцессором C из GCC. Они должны работать так же или аналогично с другими c-перпроцессорами.
для C, используйте
cpp -dD -fpreprocessed -o output.c input.cон также работает для удаления комментариев из JSON, например, так:
cpp -P -o - - <input.json >output.jsonв случае, если ваш препроцессор C не доступен напрямую, вы можете попробовать заменить
cppСcc -E, который вызывает компилятор C, сообщающий ему остановиться после этапа препроцессора. В случае, если ваш двоичный код компилятора C неccвы можете заменитьccС именем вашего двоичного кода компилятора C, напримерclang. Обратите внимание, что не все препроцессоры поддерживают-fpreprocessed.
Я знаю, что уже поздно, но я думал, что поделюсь своим кодом и моей первой попыткой написать компилятор.
Примечание: это не учитывает
"\*/"внутри многострочного комментария, например/\*...."*/"...\*. Опять же, gcc 4.8.1 тоже не делает.void function_removeComments(char *pchar_sourceFile, long long_sourceFileSize) { long long_sourceFileIndex = 0; long long_logIndex = 0; int int_EOF = 0; for (long_sourceFileIndex=0; long_sourceFileIndex < long_sourceFileSize;long_sourceFileIndex++) { if (pchar_sourceFile[long_sourceFileIndex] == '/' && int_EOF == 0) { long_logIndex = long_sourceFileIndex; // log "possible" start of comment if (long_sourceFileIndex+1 < long_sourceFileSize) // array bounds check given we want to peek at the next character { if (pchar_sourceFile[long_sourceFileIndex+1] == '*') // multiline comment { for (long_sourceFileIndex+=2;long_sourceFileIndex < long_sourceFileSize; long_sourceFileIndex++) { if (pchar_sourceFile[long_sourceFileIndex] == '*' && pchar_sourceFile[long_sourceFileIndex+1] == '/') { // since we've found the end of multiline comment // we want to increment the pointer position two characters // accounting for "*" and "/" long_sourceFileIndex+=2; break; // terminating sequence found } } // didn't find terminating sequence so it must be eof. // set file pointer position to initial comment start position // so we can display file contents. if (long_sourceFileIndex >= long_sourceFileSize) { long_sourceFileIndex = long_logIndex; int_EOF = 1; } } else if (pchar_sourceFile[long_sourceFileIndex+1] == '/') // single line comment { // since we know its a single line comment, increment file pointer // until we encounter a new line or its the eof for (long_sourceFileIndex++; pchar_sourceFile[long_sourceFileIndex] != '\n' && pchar_sourceFile[long_sourceFileIndex] != ''; long_sourceFileIndex++); } } } printf("%c",pchar_sourceFile[long_sourceFileIndex]); } }
#include<stdio.h> { char c; char tmp = ''; int inside_comment = 0; // A flag to check whether we are inside comment while((c = getchar()) != EOF) { if(tmp) { if(c == '/') { while((c = getchar()) !='\n'); tmp = ''; putchar('\n'); continue; }else if(c == '*') { inside_comment = 1; while(inside_comment) { while((c = getchar()) != '*'); c = getchar(); if(c == '/'){ tmp = ''; inside_comment = 0; } } continue; }else { putchar(c); tmp = ''; continue; } } if(c == '/') { tmp = c; } else { putchar(c); } } return 0; }эта программа работает для обоих условий, т. е. / / и/...../
Comments