it-swarm.com.de

Entfernen Sie Kommentare aus C/C++ - Code

Gibt es eine einfache Möglichkeit, Kommentare aus einer C/C++ - Quelldatei zu entfernen, ohne eine Vorverarbeitung durchzuführen. (dh ich denke, Sie können gcc -E verwenden, aber dies wird Makros erweitern.) Ich möchte nur, dass der Quellcode mit Kommentaren entfernt wird.

BEARBEITEN:

Präferenz gegenüber einem vorhandenen Werkzeug. Ich möchte das nicht selbst mit Regex schreiben müssen, ich sehe zu viele Überraschungen im Code voraus.

64
Mike

Führen Sie den folgenden Befehl für Ihre Quelldatei aus:

gcc -fpreprocessed -dD -E test.c

Vielen Dank an KennyTM für das Finden der richtigen Flaggen. Hier ist das Ergebnis zur Vollständigkeit:

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

Das hängt davon ab, wie pervers Ihre Kommentare sind. Ich habe ein Programm scc zum Entfernen von C- und C++ - Kommentaren. Ich habe auch eine Testdatei dafür, und ich habe GCC (4.2.1 unter MacOS X) mit den Optionen in der aktuell ausgewählten Antwort ausprobiert - und GCC scheint bei einigen der abscheulich gemetzelten Kommentare in der Testfall.

NB: Dies ist kein echtes Problem - die Leute schreiben nicht so grässlichen Code.

Betrachten Sie die (Teilmenge - 36 von insgesamt 135 Zeilen) des Testfalls:

/\
*\
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 */

Auf meinem Mac lautet die Ausgabe von 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 */

Die Ausgabe von 'scc' lautet:

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.

Die Ausgabe von 'scc -C' (die Kommentare mit doppeltem Schrägstrich erkennt) ist:

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.

Source für SCC jetzt auf GitHub verfügbar

Die aktuelle Version von SCC ist 6.60 (vom 2016-06-12), obwohl die Git-Versionen am 18.01.2017 (in der Zeitzone US/Pazifik) erstellt wurden. Der Code ist auf GitHub unter https://github.com/jleffler/scc-snapshots verfügbar. Sie können auch Momentaufnahmen der Vorgängerversionen (4.03, 4.04, 5.05) und zwei Vorabversionen (6.16, 6.50) finden - diese sind alle mit release/x.yz gekennzeichnet.

Der Code wird immer noch hauptsächlich unter RCS entwickelt. Ich arbeite noch daran, wie ich Submodule oder einen ähnlichen Mechanismus verwenden möchte, um mit gängigen Bibliotheksdateien wie stderr.c und stderr.h umzugehen (die auch in https://github.com/jleffler/soq zu finden sind.) .

SCC-Version 6.60 versucht, C++ 11-, C++ 14- und C++ 17-Konstrukte wie Binärkonstanten, numerische Interpunktionszeichen, rohe Zeichenfolgen und hexadezimale Gleitkommas zu verstehen. Die Standardeinstellung ist der C11-Modus. (Beachten Sie, dass die oben erwähnte Bedeutung des -C-Flags zwischen der im Hauptteil der Antwort beschriebenen Version 4.0x und der aktuell aktuellen Version 6.60 geändert wurde.)

13

Es gibt ein stripcmt -Programm, das dies tun kann:

StripCmt ist ein einfaches Programm, das in C geschrieben wurde, um Kommentare aus C-, C++ - und Java-Quelldateien zu entfernen. In der Tradition von Unix-Textverarbeitungsprogrammen kann es entweder als FIFO (First In - First Out) -Filter fungieren oder Argumente in der Befehlszeile akzeptieren.

(per hlovdal s Antwort auf: Frage zu Python-Code für dieses )

7
che

gcc -fpreprocessed -dD -E hat bei mir nicht funktioniert, aber dieses Programm macht es:

#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

Dies ist ein Perl-Skript zum Entfernen von // einzeiligen und/* mehrzeiligen Kommentaren

  #!/usr/bin/Perl

  undef $/;
  $text = <>;

  $text =~ s/\/\/[^\n\r]*(\n\r)?//g;
  $text =~ s/\/\*+([^*]|\*(?!\/))*\*+\///g;

  print $text;

Es erfordert Ihre Quelldatei als Befehlszeilenargument. Speichern Sie das Skript in einer Datei, beispielsweise remove_comments.pl Und rufen Sie es mit folgendem Befehl auf: Perl -w remove_comments.pl

Ich hoffe es wird hilfreich sein

4
Vladimir

Ich hatte auch dieses Problem. Ich habe dieses Tool ( Cpp-Decomment ) gefunden, das für mich funktioniert hat. Es wird jedoch ignoriert, wenn sich die Kommentarzeile bis zur nächsten Zeile erstreckt. Z.B:

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

In diesem Fall konnte ich keinen Weg im Programm finden, also suchte ich nach ignorierten Zeilen und reparierte sie manuell. Ich glaube, dass es eine Option dafür gibt oder Sie könnten die Quelldatei des Programms ändern, um dies zu tun. 

3

Ich schreibe ein C-Programm unter Verwendung einer Standard-C-Bibliothek mit etwa 200 Zeilen, die Kommentare aus der C-Quellcodedatei entfernt. qeatzy/removeccomments

verhalten

  1. Kommentar im C-Stil, der sich über mehrere Zeilen erstreckt oder die gesamte Zeile belegt, wird auf Null gesetzt.
  2. C-Stil-Kommentar in der Mitte einer Zeile bleiben unverändert. zB void init(/* do initialization */) {...}
  3. Kommentar im C++ - Stil, der die gesamte Zeile belegt, wird auf Null gesetzt.
  4. C-String-Literal wird eingehalten, indem " Und \" Überprüft werden.
  5. kümmert sich um die Fortsetzung der Zeile. Wenn die vorherige Zeile mit \ Endet, ist die aktuelle Zeile Teil der vorherigen Zeile.
  6. zeilennummer bleiben gleich. Herausgenommene Zeilen oder Teilzeilen werden leer.

testen & Profilieren

Ich habe mit dem größten Cpython-Quellcode, der viele Kommentare enthält getestet. In diesem Fall erledigt es die Aufgabe richtig und schnell 2-5 schneller als gcc

time gcc -fpreprocessed -dD -E Modules/unicodeobject.c > res.c 2>/dev/null
time ./removeccomments < Modules/unicodeobject.c > result.c

verwendungszweck

/path/to/removeccomments < input_file > output_file
1
qeatzy

Da Sie C verwenden, möchten Sie möglicherweise etwas verwenden, das für C "natürlich" ist. Sie können den C-Präprozessor verwenden, um nur Kommentare zu entfernen. Die unten aufgeführten Beispiele arbeiten mit dem C-Präprozessor von GCC zusammen. Sie sollten genauso oder in ähnlicher Weise mit anderen C-Perprozessoren zusammenarbeiten.

Für C verwenden

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

Es funktioniert auch zum Entfernen von Kommentaren aus JSON, zum Beispiel wie folgt:

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

Falls auf Ihren C-Präprozessor nicht direkt zugegriffen werden kann, können Sie versuchen, cpp durch cc -E zu ersetzen, wodurch der C-Compiler aufgerufen wird, ihn nach der Präprozessorstufe zu stoppen. Falls Ihr C-Compiler-Binary nicht cc ist, können Sie cc durch ersetzen der Name Ihrer C-Compiler-Binärdatei, zum Beispiel clang. Beachten Sie, dass nicht alle Präprozessoren -fpreprocessed unterstützen.

1
Christian Hujer

Ich glaube Wenn Sie eine Aussage verwenden, können Sie Kommentare von C leicht entfernen

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

Nur Problem mit diesem Befehl kann Kommentare, die mehr als eine Zeile enthalten, nicht entfernen. Mit diesem RegEx können Sie jedoch leicht Logik für das Entfernen von Kommentaren mit mehreren Zeilen implementieren

0
Poseidon_Geek

Kürzlich habe ich Ruby-Code geschrieben, um dieses Problem zu lösen. Ich habe folgende Ausnahmen betrachtet:

  • kommentar in Strings
  • mehrzeiliger Kommentar in einer Zeile, gierige Übereinstimmung korrigieren.
  • mehrere Zeilen auf mehreren Zeilen

Hier ist der Code :

Es verwendet den folgenden Code, um jede Zeile vorzuverarbeiten, falls diese Kommentare in Zeichenfolgen angezeigt werden. Wenn es in Ihrem Code erscheint, äh, Pech. Sie können es durch komplexere Zeichenfolgen ersetzen.

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

VERWENDUNG: Ruby -w inputfile outputfile

0
chunyang.wen