web-dev-qa-db-fra.com

Supprimer les commentaires du code C/C++

Existe-t-il un moyen simple de supprimer des commentaires d’un fichier source C/C++ sans effectuer aucun traitement préalable? (Par exemple, je pense que vous pouvez utiliser gcc -E mais cela développera les macros.) Je veux juste que le code source ne comporte pas de commentaires, rien d'autre ne devrait être changé.

MODIFIER:

Préférence envers un outil existant. Je ne veux pas avoir à écrire moi-même avec des regex, je prévois trop de surprises dans le code.

64
Mike

Exécutez la commande suivante sur votre fichier source:

gcc -fpreprocessed -dD -E test.c

Merci à KennyTM d’avoir trouvé les bons drapeaux. Voici le résultat pour être complet:

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

Cela dépend de la perversité de vos commentaires. J'ai un programme scc pour supprimer les commentaires C et C++. J'ai aussi un fichier de test, et j'ai essayé GCC (4.2.1 sur MacOS X) avec les options de la réponse actuellement sélectionnée - et GCC ne semble pas faire un travail parfait sur certains des commentaires horriblement bouchés du cas de test.

NB: Ce n'est pas un problème réel - les gens n'écrivent pas un code aussi horrible.

Considérons le (sous-ensemble - 36 lignes sur 135 au total) du scénario de test:

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

Sur mon Mac, le résultat de GCC (gcc -fpreprocessed -dD -E subset.c) est le suivant:

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

Le résultat de 'scc' est:

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.

La sortie de 'scc -C' (qui reconnaît les commentaires à double barre oblique) est:

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.

La source de SCC maintenant disponible sur GitHub

La version actuelle de SCC est la version 6.60 (datée du 2016-06-12), bien que les versions de Git aient été créées le 2017-01-18 (dans le fuseau horaire des États-Unis et du Pacifique). Le code est disponible auprès de GitHub à l’adresse https://github.com/jleffler/scc-snapshots . Vous pouvez également trouver des instantanés des versions précédentes (4.03, 4.04, 5.05) et des deux versions préliminaires (6.16, 6.50) - elles sont toutes balisées avec release/x.yz.

Le code est encore principalement développé sous RCS. Je cherche toujours à utiliser des sous-modules ou un mécanisme similaire pour gérer les fichiers de bibliothèque courants tels que stderr.c et stderr.h (qui se trouve également dans https://github.com/jleffler/soq ). .

SCC version 6.60 tente de comprendre les constructions C++ 11, C++ 14 et C++ 17 telles que les constantes binaires, la ponctuation numérique, les chaînes brutes et les flottants hexadécimaux. Il utilise par défaut le mode C11. (Notez que la signification de l'indicateur -C - mentionné ci-dessus - est basculée entre la version 4.0x décrite dans le corps principal de la réponse et la version 6.60, qui est actuellement la dernière version.)

13
Jonathan Leffler

Il existe un programme stripcmt qui peut le faire:

StripCmt est un utilitaire simple écrit en C pour supprimer les commentaires des fichiers source C, C++ et Java. Dans la grande tradition des programmes de traitement de texte Unix, il peut fonctionner comme filtre FIFO (Premier entré - Premier sorti) ou accepter des arguments sur la ligne de commande.

(per hlovdal réponse de/à: question sur le code Python pour cela )

7
che

gcc -fpreprocessed -dD -E n'a pas fonctionné pour moi mais ce programme fonctionne

#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

Ceci est un script Perl pour supprimer // une ligne et/* plusieurs lignes */comments

  #!/usr/bin/Perl

  undef $/;
  $text = <>;

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

  print $text;

Votre fichier source doit être utilisé comme argument de ligne de commande. Enregistrez le script dans un fichier, supposons que remove_comments.pl Et appelez-le à l’aide de la commande suivante: Perl -w remove_comments.pl [votre fichier source]

J'espère que ça vous sera utile

4
Vladimir

J'ai eu ce problème aussi. J'ai trouvé cet outil ( Cpp-Decomment ), qui a fonctionné pour moi. Cependant, il ignore si la ligne de commentaire s'étend à la ligne suivante. Par exemple:

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

Dans ce cas, je ne pouvais pas trouver un moyen dans le programme, donc j'ai juste cherché les lignes ignorées et corrigé manuellement. Je crois qu'il y aurait une option pour cela ou peut-être que vous pourriez changer le fichier source du programme pour le faire. 

3
Halil Kaskavalci

Parce que vous utilisez C, vous pouvez utiliser quelque chose qui est "naturel" à C. Vous pouvez utiliser le préprocesseur C pour simplement supprimer les commentaires. Les exemples donnés ci-dessous fonctionnent avec le préprocesseur C de GCC. Ils doivent également fonctionner de la même manière ou de manière similaire avec d’autres processeurs C.

Pour C, utilisez

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

Cela fonctionne également pour supprimer des commentaires de JSON, par exemple comme ceci:

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

Si votre préprocesseur C n’est pas directement accessible, vous pouvez essayer de remplacer cpp par cc -E, qui appelle le compilateur C lui demandant de s’arrêter après l’étape du préprocesseur . Si votre fichier binaire du compilateur C n’est pas cc, vous pouvez remplacer cc par le nom de votre binaire du compilateur C, par exemple clang. Notez que tous les préprocesseurs ne prennent pas en charge -fpreprocessed.

1
Christian Hujer

Je crois que si vous utilisez une déclaration, vous pouvez facilement supprimer les commentaires de 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

Seul problème avec cette commande, il ne peut pas supprimer les commentaires qui contiennent plus d’une ligne. Mais en utilisant ce regEx, vous pouvez facilement implémenter la logique pour supprimer plusieurs commentaires

0
Poseidon_Geek

Récemment, j'ai écrit du code Ruby pour résoudre ce problème. J'ai envisagé les exceptions suivantes:

  • commenter en chaînes
  • commentaire de ligne multiple sur une ligne, correction du match glouton.
  • plusieurs lignes sur plusieurs lignes

Voici le code :

Il utilise le code suivant pour prétraiter chaque ligne au cas où ces commentaires apparaissent dans des chaînes. Si cela apparaît dans votre code, euh, pas de chance. Vous pouvez le remplacer par une chaîne plus complexe.

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

USAGE: Ruby -w inputfile outputfile

0
chunyang.wen