Remove comments from C / C ++ code

Is there an easy way to remove comments from a C / C ++ source file without preprocessing. (i.e. I think you can use gcc -E, but that will expand the macros.) I just want the source code with comments to be stripped, nothing else needs to be changed.

EDIT:

Preference for an existing tool. I don’t want to write this myself using regular expressions; I foresee too many surprises in the code.

+61
c ++ c comments
Mar 06 '10 at 20:29
source share
12 answers

Run the following command in your source file:

gcc -fpreprocessed -dD -E test.c 

Thanks to KennyTM for finding the right flags. Here is the result for completeness:

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 
+87
Mar 06
source share
β€” -

It depends on how perverted your comments are. I have an scc program to remove C and C ++ comments. I also have a test file for it, and I tried GCC (4.2.1 on MacOS X) with options in the currently selected answer - and GCC does not seem to cope with some of the badly killed comments in a use case.

NB: This is not a real life problem - people don’t write such awful code.

Consider (a subset of 36 of 135 lines) a test case:

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

On my Mac, the output from 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 */ 

Output from '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. 

Output from 'scc -C' (which recognizes double slash comments):

 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 source code is now available on GitHub

The current version of SCC is 6.60 (from 2016-06-12), although Git versions were created 2017-01-18 (in the US / Pacific time zone). The code is available on GitHub at https://github.com/jleffler/scc-snapshots . You can also find snapshots of previous releases (4.03, 4.04, 5.05) and two preliminary releases (6.16, 6.50) - all of them are marked as release/x.yz

The code is still mainly developed under RCS. I am still working on how I want to use stderr.c or a similar mechanism to work with shared libraries like stderr.c and stderr.h (which can also be found at https://github.com/jleffler/soq ).,

Version 6.60 SCC attempts to understand the constructs of C ++ 11, C ++ 14, and C ++ 17, such as binary constants, numerical punctuation, raw strings, and hexadecimal floating point numbers. The default mode is C11. (Note that the value of the -C flag - mentioned above - switched between version 4.0x, which is described in the main body of the response, and version 6.60, which is currently the latest version.)

+13
Mar 07 '10 at 2:18
source share

gcc -fpreprocessed -dD -E did not work for me, but this program does this:

 #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
Mar 07 '10 at 3:14
source share

There is a stripcmt program, than this can be done:

StripCmt is a simple utility written in C to remove comments from C, C ++, and Java source files. In the great tradition of Unix word processing programs, it can function as either a FIFO (First In-First Out) filter or accept arguments on the command line.

(for hlovdal answer the question about Python code for this )

+7
Apr 04 2018-11-11T00:
source share

This is a perl script to remove // ​​single-line and / * multi-line * / comments

  #!/usr/bin/perl undef $/; $text = <>; $text =~ s/\/\/[^\n\r]*(\n\r)?//g; $text =~ s/\/\*+([^*]|\*(?!\/))*\*+\///g; print $text; 

It requires your source file to be a command line argument. Save the script to a file, say remove_comments.pl and call it using the following command: perl -w remove_comments.pl [your source file]

Hope this will be helpful

+4
Aug 15 2018-12-12T00:
source share

I also had this problem. I found this tool ( Cpp-Decomment ) that worked for me. However, it ignores if the comment line continues to the next line. For example:

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

In this case, I could not find a way in the program, so I just looked for the lines and fixed them manually. I believe that there would be an option for this, or perhaps you could modify the source program file for this.

+3
Sep 25
source share

Since you are using C, you can use something that is "natural" for C. You can use the C preprocessor to simply delete comments. The examples below work with the C preprocessor from GCC. They should work the same or similarly with other C processors.

For C use

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

It also works to remove comments from JSON, for example:

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

If your C preprocessor is not directly accessible, you can try replacing cpp with cc -E , which calls the C compiler, telling it to stop working after the preprocessor step. In case your C compiler is not cc , you can replace cc with the name of your binary C compiler, for example clang . Note that not all preprocessors support -fpreprocessed .

+1
May 08 '17 at 11:26
source share

I am writing a C program using the standard C library, about 200 lines, which removes comments from a source file in C. qeatzy / removeccomments

behavior

  1. A C-style comment that spans multiple lines or spans an entire line is nullified.
  2. A C-style comment in the middle of the line remains unchanged. for example, void init(/* do initialization */) {...}
  3. A C ++ style comment that spans the entire line is nullified.
  4. The string literal C is respected by checking " and \" .
  5. handles line continuation. If the previous line ends with \ , the current line is part of the previous line.
  6. line number remains the same. Strikethrough lines or part of a line become empty.

testing and profiling

I tested the largest cpython source code that contains a lot of comments. In this case, it does the job correctly and quickly, 2-5 times faster than gcc

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

using

 /path/to/removeccomments < input_file > output_file 
+1
Nov 30 '18 at 5:17
source share

I believe. If you use one expression, you can easily remove Comments from 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 

Only a problem with this command does not delete comments containing more than one line. But with this regEx you can easily implement the logic for Multiline Removing comments

0
Aug 08 '12 at 18:38
source share

I recently wrote Ruby code to solve this problem. I have considered the following exceptions:

  • comment in lines
  • multi-line comment on one line, correction of greedy coincidence.
  • several lines to several lines

Here is the code :

It uses the following code to preprocess each line in case these comments appear in the lines. If this appears in your code, no luck. You can replace it with more complex strings.

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

USE: ruby -w inputfile outputfile

0
Apr 24 '14 at 1:25
source share

I know this late, but I decided to share my code and the first attempt to write a compiler.

Note. This does not account for "\*/" inside a multi-line comment, for example, /\*...."*/"...\* . Again, gcc 4.8.1 does not work either.

 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] != '\0'; long_sourceFileIndex++); } } } printf("%c",pchar_sourceFile[long_sourceFileIndex]); } } 
-one
Jul 12 '14 at 17:32
source share
 #include<stdio.h> { char c; char tmp = '\0'; 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 = '\0'; putchar('\n'); continue; }else if(c == '*') { inside_comment = 1; while(inside_comment) { while((c = getchar()) != '*'); c = getchar(); if(c == '/'){ tmp = '\0'; inside_comment = 0; } } continue; }else { putchar(c); tmp = '\0'; continue; } } if(c == '/') { tmp = c; } else { putchar(c); } } return 0; } 

This program is executed for both conditions ie // and /...../

-3
Jul 02 '13 at 10:57 on
source share



All Articles