web-dev-qa-db-ja.com

C / C ++コードからコメントを削除する

前処理を行わずにC/C++ソースファイルからコメントを削除する簡単な方法はありますか。 (つまり、gcc -Eを使用できると思いますが、これによりマクロが展開されます。)コメントが削除されたソースコードが必要なだけです。他に変更はありません。

編集:

既存のツールに対する選好。私は正規表現でこれを自分で書く必要はありません、私はコードにあまりにも多くの驚きを予見しています。

65
Mike

ソースファイルで次のコマンドを実行します。

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
96
Josh Lee

それはあなたのコメントがどれほどひどいものかによる。 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=のソースがGitHubで利用可能になりました

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.hhttps://github.com/jleffler/soq にもあります)。

SCCバージョン6.60は、バイナリ定数、数字の句読点、生の文字列、16進浮動小数点などのC++ 11、C++ 14、およびC++ 17の構造を理解しようとします。デフォルトではC11モードで動作します。 (注意:-Cフラグ—上記のとおり—回答の本文に記載されているバージョン4.0xと、現在の最新リリースであるバージョン6.60の間で反転しました。)

14

これを行うことができる stripcmt プログラムがあります。

StripCmtは、C、C++、およびJavaソースファイルからコメントを削除するためにCで記述されたシンプルなユーティリティです。Unixテキスト処理プログラムの伝統では、FIFO(先入れ先出し)コマンドラインで引数をフィルターまたは受け入れる。

hlovdal の答え: Pythonのコード )についての質問)

7
che

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
lhf

これは、// 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 [ソースファイル]

お役に立てば幸いです

4
Vladimir

私もこの問題を抱えていました。このツール( Cpp-Decomment )が見つかりました。ただし、コメント行が次の行に及ぶ場合は無視されます。例えば:

// this is my comment \
comment continues ...

この場合、プログラムで方法を見つけることができなかったため、無視された行を検索し、手動で修正しました。そのためのオプションがあるか、プログラムのソースファイルを変更して変更できると思います。

3

Cソースコードファイルのコメントを削除する、約200行の標準Cライブラリを使用してCプログラムを作成します。 qeatzy/removeccomments

動作

  1. 複数行にわたる、または行全体を占めるCスタイルのコメントはゼロになります。
  2. 行の途中のCスタイルのコメントは変更されません。たとえば、void init(/* do initialization */) {...}
  3. 行全体を占めるC++スタイルのコメントはゼロになります。
  4. "および\"を確認することにより、C文字列リテラルが尊重されます。
  5. 行継続を処理します。前の行が\で終わる場合、現在の行は前の行の一部です。
  6. 行番号は同じままです。ゼロ化された行または行の一部は空になります。

テストとプロファイリング

多くのコメントを含む最大の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
1
qeatzy

Cを使用しているため、Cに「自然な」ものを使用したい場合があります。Cプリプロセッサーを使用して、コメントを削除することができます。以下に示す例は、GCCのCプリプロセッサで動作します。他のCパープロセッサでも同じように、または同様に機能するはずです。

Cの場合、使用

cpp -dD -fpreprocessed -o output.c input.c

また、次のように、JSONからコメントを削除するためにも機能します。

cpp -P -o - - <input.json >output.json

Cプリプロセッサに直接アクセスできない場合は、cppcc -Eに置き換えることができます。これは、プリプロセッサステージの後に停止するようにCコンパイラを呼び出します。 Cコンパイラバイナリがccでない場合は、ccをCコンパイラバイナリの名前で置き換えることができます(例:clang)。すべてのプリプロセッサが-fpreprocessedをサポートしているわけではないことに注意してください。

1
Christian Hujer

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

このコマンドの唯一の問題は、複数の行を含むコメントを削除できないことですが、この正規表現を使用すると、複数行のコメントを削除するためのロジックを簡単に実装できます

0
Poseidon_Geek

最近、この問題を解決するためにRubyコードを書きました。次の例外を検討しました。

  • 文字列のコメント
  • 1行に複数行コメント、貪欲な一致を修正。
  • 複数行の複数行

code は次のとおりです。

これらのコメントが文字列に表示される場合、次のコードを使用して各行を前処理します。コードに表示されている場合は、運が悪いです。より複雑な文字列に置き換えることができます。

  • MUL_REPLACE_LEFT = "MUL_REPLACE_LEFT"
  • MUL_REPLACE_RIGHT = "MUL_REPLACE_RIGHT"
  • SIG_REPLACE = "SIG_REPLACE"

使用法: Ruby -w inputfile outputfile

0
chunyang.wen