前処理を行わずにC/C++ソースファイルからコメントを削除する簡単な方法はありますか。 (つまり、gcc -Eを使用できると思いますが、これによりマクロが展開されます。)コメントが削除されたソースコードが必要なだけです。他に変更はありません。
編集:
既存のツールに対する選好。私は正規表現でこれを自分で書く必要はありません、私はコードにあまりにも多くの驚きを予見しています。
ソースファイルで次のコマンドを実行します。
gcc -fpreprocessed -dD -E test.c
正しいフラグを見つけてくれたKennyTMに感謝します。完全性の結果は次のとおりです。
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
それはあなたのコメントがどれほどひどいものかによる。 CとC++のコメントを削除するプログラムscc
があります。また、テストファイルもあり、現在選択されている回答のオプションを使用してGCC(MacOS Xの4.2.1)を試しました。GCCは、恐ろしく屠殺されたコメントのいくつかに対して完璧な仕事をしていないようです。テストケース。
テストケースの(サブセット-合計135行のうち36行)を検討します。
/\
*\
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(2016-06-12日付))ですが、Gitバージョンは2017-01-18(米国/太平洋時間帯)に作成されました。コードはGitHubの https://github.com/jleffler/scc-snapshots から入手できます。以前のリリース(4.03、4.04、5.05)と2つのプレリリース(6.16、6.50)のスナップショットもあります。 )—これらはすべてタグ付きrelease/x.yz
。
コードは現在も主にRCSで開発されています。私はまだサブモジュールまたは同様のメカニズムを使用してstderr.c
およびstderr.h
( https://github.com/jleffler/soq にもあります)。
SCCバージョン6.60は、バイナリ定数、数字の句読点、生の文字列、16進浮動小数点などのC++ 11、C++ 14、およびC++ 17の構造を理解しようとします。デフォルトではC11モードで動作します。 (注意:-C
フラグ—上記のとおり—回答の本文に記載されているバージョン4.0xと、現在の最新リリースであるバージョン6.60の間で反転しました。)
これを行うことができる stripcmt プログラムがあります。
StripCmtは、C、C++、およびJavaソースファイルからコメントを削除するためにCで記述されたシンプルなユーティリティです。Unixテキスト処理プログラムの伝統では、FIFO(先入れ先出し)コマンドラインで引数をフィルターまたは受け入れる。
( hlovdal の答え: Pythonのコード )についての質問)
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;
}
これは、// 1行および/ *複数行* /コメントを削除する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ソースコードファイルのコメントを削除する、約200行の標準Cライブラリを使用してCプログラムを作成します。 qeatzy/removeccomments
void init(/* do initialization */) {...}
"
および\"
を確認することにより、C文字列リテラルが尊重されます。\
で終わる場合、現在の行は前の行の一部です。多くのコメントを含む最大のcpythonソースコードでテストしました。この場合、ジョブは正しく、高速に、2-5高速gccより
time gcc -fpreprocessed -dD -E Modules/unicodeobject.c > res.c 2>/dev/null
time ./removeccomments < Modules/unicodeobject.c > result.c
/path/to/removeccomments < input_file > output_file
Cを使用しているため、Cに「自然な」ものを使用したい場合があります。Cプリプロセッサーを使用して、コメントを削除することができます。以下に示す例は、GCCのCプリプロセッサで動作します。他の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
をサポートしているわけではないことに注意してください。
1つのステートメントを使用すると、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コードを書きました。次の例外を検討しました。
code は次のとおりです。
これらのコメントが文字列に表示される場合、次のコードを使用して各行を前処理します。コードに表示されている場合は、運が悪いです。より複雑な文字列に置き換えることができます。
使用法: Ruby -w inputfile outputfile