I have a C source file having comments in //
(C++) style. I want to change all the comments to the old /* */
(C) style. Is there a way to do this using an existing script?
-
1Are you using a pre-C99 version of C? Per my experience and the wiki page (http://en.wikipedia.org/wiki/C_(programming_language)) `//` style comments are allowed C99 onwards. If the coding standard has any limit on line length (e.g. Google Coding Style recommends max 80 chars), you have to watch out for that too. There may be cases like what pmg mentions below. Overall, I am curious to know, what's your motivation. – Arun Oct 22 '10 at 19:14
-
2A good reason for doing this is to get code to compile cleanly with compilers that either don't support C++ style comments or complain about them with the particular C version specified. – nategoose Oct 22 '10 at 19:25
-
I'm expected to write ANSI-compliant code as far as possible. So I checking off all the errors that `gcc -ansi` is turning up. – Oct 22 '10 at 19:28
-
2`gcc -ansi` will change to support C99 some time (soon, we hope). If you really need C89 compatibility, use `gcc -std=c89 -pedantic` – pmg Oct 22 '10 at 19:31
-
For something over a decade now, `//` comments have been perfectly standard C, and as ISO-compliant as `int`. (The original C standard, in 1989, was an ANSI standard. I believe the C++ and C99 standards were ISO only, as far as I know.) – David Thornley Oct 22 '10 at 20:06
8 Answers
A substitution with you favorite editor and a regular expression like s#//(.*)#/*\1 */#
should do it...

- 222,467
- 53
- 283
- 367
-
1
-
doesn't work for me in vi (throws `Pattern not found: //(.*)`) what does hash do? – N 1.1 Oct 22 '10 at 19:08
-
2@N 1.1: The hash is just a placeholder, it can be any character. It's usually a forward slash, but when you have slashes in your pattern, it's easier to use a different delimiter than it is to escape all of your slashes. `s/foo/bar/` is equivalent to `s#foo#bar#`, `sXfooXbarX`, and `s,foo,bar,` etc. – Adam Rosenfield Oct 22 '10 at 19:17
-
2@N 1.1: In vi, I think you need to escape the parenthesis to make them capture (unescaped they match the text) `:s#//\\(.*\\)#/*\1 */#`. The '#' serve to delimit the search and the substitution (usually done with '/', but using '#' allows to replace '/'s without escaping) – pmg Oct 22 '10 at 19:19
-
1@N 1.1: The default seporator for search and replace in vi is '/' but you can actually use any character. Whcih is usefull when the search string contains the '/' character (otherwise you need to escape its usage). With vi you need to escape the '(' and ')' so you end up with `: % s#//\\(.*\\)$#/*\1*/#` – Martin York Oct 22 '10 at 19:22
If you are looking for something a little more generic, you could also use a source code formatting tool for this. For C, I've used uncrustify before and it worked reasonably well. There may be others as well, but I think uncrustify can change C++ style comments into C style comments with the cmt_cpp_to_c
parameter.
The configuration can be a little daunting, but if you just use the example config file and change only the stuff you are interested in, it might do what you want.

- 5,896
- 2
- 31
- 42
Well, 1,$s#//\(.*\)#/*\1 */#
will work only if you have no instances of C++-style comments within (usually multi-line) C-style comments, since the substitution will prematurely end the C-style comment, leaving the remaining portion of the C-style comment without a starting /*
.
Any regular C++-style comment that has */
within it will also cause problems. This happens in code where a bad programmer changed a C-style comment to a C++-style comment without removing the ending */
.

- 11
- 1
Unfortunately most scripts will only work the other way around. There is a decent one named "RECOMMENT" but it takes C and converts to the newer C++ style comments. I imagine your reason for wanting to do this is due to compiler errors with the C++ style comments. The usual cause of this is a line that uses a C-style comment with an C++ style comment. Perhaps looking for that particular scenario would eliminate your need to convert back to older style commenting. If not, sadly you might have to do it by hand. (I pray that you don't as I know how tedious that can be!)
Recomment Link: http://people.sc.fsu.edu/~jburkardt/cpp_src/recomment/recomment.html

- 1,199
- 5
- 19
- 42
-
I'll keep that in mind for when I need it. You may want to provide a link to RECOMMENT in your answer. – Oct 22 '10 at 19:13
-
1Scripts that do this the other way round are scary. `/* foo */ bar++;` can't be translated correctly without changing line numbering. – nategoose Oct 22 '10 at 19:21
-
I apologize for forgetting the link! I have updated my answer with the link at the bottom! – D.R. Oct 22 '10 at 19:51
You can do this with the Vim plugin Nerdcommenter.
This makes it easy to uncomment the text and then add a multi-line comment like you want.

- 122,701
- 101
- 260
- 319
This is a simple problem on the surface, but a very difficult problem to handle all the edge cases. The simple solution is easily implemented in sed:
sed -e 'sX// *\(.*[^ ]\) *$X/* \1 */X' < oldfile > newfile
You can adjust that as needed: I have it eat all the spaces at the start and end of the comment.
What this doesn't handle is new-style comments with embedded old-style comments (as others have noted). What this really messes up is strings with double-slashes in them--they're not comments, but without parsing the strings, they'll get modified as if they were. Check for those:
egrep '//.*/[*]|".*//' oldfile
If you hit any of those, they'll require manual correction. Any attempt to automate it without actually parsing the file will just create new and more convoluted edge conditions, though you may recognize a pattern for a hack that is good enough for your situation.

- 91
- 1
- 3
Vim Nerdcommenter alternate delims map
If you do: <leader>ca
some file types have alternate comment styles, and in particular for C / C++ it allows switching between //
and /*
, tested in 2.5.2.
You may then also be interested in the "sexy comments mode" used with <leader>cs
which does nice C multiline comments as mentioned at: NERD commenter : How to comment out a range

- 347,512
- 102
- 1,199
- 985
For all the coders out there! The below solution works with Eclipse, Sublime and other editors that support Regular expressions.
- Bring-up find and replace in sublime
- Make sure Regular Expression option is enabled (Alt+R)
- Enter in Find: //(.*)
- Enter in Replace /*\1 */
voilà!

- 197
- 1
- 1
- 17