1

I have a directory of C files. I want to remove all types of comments from these source files.

For example, let's say I have a source code that is similar to the following file.

#include <stdio.h>
int main() {   
 int number;
 /* Sample Multiline Comment 
 * Line 1
 * Line 2
 */
 printf("Enter an integer: ");  

 // reads and stores input
 scanf("%d", &number);
 printf("You entered: %d", number); //display output 

 return 0;
 /* Comment */
}

I want to remove all types of comments in this code. This includes,

//    
/* */   
/*
*
*/

I have attempted to carry out this task by using a sed command.

find . -type f |xargs sed -i 's,/\*\*,,g;s,\*/,,g;s,/\*,,g;s,//,,g'

This only removes the above comment symbols itself but not the comment. I would like to remove the entire comment along with the above three comment symbols.

How can I achieve this criteria.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
coder
  • 203
  • 5
  • 15
  • 1
    IMHO I don't think any other tool is good for this task, this may lead to False Positives too. So better why not use something in that language itself I googles and found one link https://www.geeksforgeeks.org/remove-comments-given-cc-program/ take a look if this helps you? – RavinderSingh13 Jan 08 '20 at 05:26
  • @coder: Did you think of statements such as `strcpy(s, "// this is not a comment")`? – user1934428 Jan 08 '20 at 08:23
  • 1
    Does this answer your question? [Remove comments from C/C++ code](https://stackoverflow.com/questions/2394017/remove-comments-from-c-c-code) – Jon Jan 08 '20 at 10:13

3 Answers3

0

Approach this from two perspectives.

  1. You delete a line that starts with your matching criteria
  2. You delete content that starts with some criteria and ends with different criteria.

To delete a line that starts with criteria:

sed '/^\/\// d'

To delete between a start and finish use:

sed 's/\/\*.*\*\/://'

Warning. Be careful when you have other lines that may start with the applicable characters.

I hope this is what you are looking for.

agent82
  • 1
  • 2
  • Sorry this doesn't do the trick for me. I ran the following command with your code, find . -type f |xargs sed -i '/^\/\// d' However, it shows no effect. – coder Jan 08 '20 at 05:53
  • @agent82 : Be careful when doing this line-oriented. A C-program may have a logical line spanning several physical lines, by ending a line with a backslash. – user1934428 Jan 08 '20 at 08:25
  • What about find .. -type f -print0 | xargs -0 sed -i '/^\/\// d' . Also try to use the sed command on a cat of one file first to make sure it does what you want before you daisychain it to a find. – agent82 Jan 08 '20 at 09:22
  • @agent82 no it still doesn't work – coder Jan 08 '20 at 10:06
0

This is kind of a time-pass try with awk, but maybe it helps:

#! /usr/bin/env bash    

awk '
    function remove_comments(line)
    {
        # multi-line comment is active, clear everything
        if (flag_c == 1) {

            if (sub(/.*[*][\/]$/, "", line)) {
                flag_c=0
            }
            else {
                # skip this line
                # its all comment
                return 1
            }

        }

        # remove multi-line comments(/**/) made on the same line
        gsub(/[\/][*].*[*][\/]/, "", line)

        # remove single line comments if any
        sub(/[\/][\/].*$/, "", line)

        # make flag_c=1 if a multi-line comment has been started
        if (sub(/[\/][*].*/, "", line))
        {
            flag_c=1
        }

        return line
    }

    ##
    #   MAIN
    ##
    {
        $0 = remove_comments($0)

        if ($0 == 1 || $0 == "")
            next

        print
    }
' file.c
Mihir Luthra
  • 6,059
  • 3
  • 14
  • 39
  • Sorry for being nickpicking but it fails for the statement such as `printf("http://www.foo.bar");` I'm afraid we cannot remove comments robustly without a parser for the language. – tshiono Jan 09 '20 at 00:30
  • @tshiono, yes that makes sense. The script would consider `//` in the string a comment. Agreed, a parser that knows about the language is much reliable! – Mihir Luthra Jan 09 '20 at 00:38
0

You are best off using the C preprocessor for this, as in the answer for Remove comments from C/C++ code.

You can ask the preprocessor to remove comments by running gcc -fpreprocessed -dD -E foo.c.

$ cat foo.c
#include <stdio.h>
int main() {
 int number;
 /* Sample Multiline Comment
 * Line 1
 * Line 2
 */
 printf("Enter an integer: ");

 // reads and stores input
 scanf("%d", &number);
 printf("You entered: %d", number); //display output

 return 0;
 /* Comment */
}
$ gcc -fpreprocessed -dD -E foo.c
# 1 "foo.c"
#include <stdio.h>
int main() {
 int number;




 printf("Enter an integer: ");


 scanf("%d", &number);
 printf("You entered: %d", number);

 return 0;

}
Jon
  • 3,573
  • 2
  • 17
  • 24