将C++风格的注释改为C风格

11

我有一个C源代码文件,其中的注释是以//(C ++)格式编写的。我想将所有注释更改为旧的/* */(C)格式。是否有现有脚本可以实现这一功能?


1
你是否使用了C语言的C99版本之前的版本?根据我的经验和维基页面(http://en.wikipedia.org/wiki/C_(programming_language)),`//`风格的注释是从C99开始被允许的。如果编码标准对行长有任何限制(例如Google编码风格建议最大80个字符),你也必须注意这一点。可能会出现像pmg在下面提到的情况。总的来说,我很想知道你的动机是什么。 - Arun
2
这样做的一个好理由是,可以使代码在不支持C++风格注释或者对指定的特定C版本抱怨它们的编译器中干净地编译。 - nategoose
我需要尽可能地编写符合ANSI标准的代码。因此,我正在核对所有gcc -ansi检测到的错误。 - user191776
2
gcc -ansi 将在不久的将来改为支持 C99。如果您确实需要 C89 兼容性,请使用 gcc -std=c89 -pedantic - pmg
现在已经有十多年了,//注释一直是标准的C语言,并且与int一样符合ISO标准。(最初的C标准是1989年的ANSI标准。据我所知,C++和C99标准仅限于ISO标准。) - David Thornley
8个回答

14

使用您最喜欢的编辑器和类似于s#//(.*)#/*\1 */#的正则表达式进行替换即可...


注:原文中的代码部分已经是 HTML 标签,无需特殊处理。

1
只需注意 x=0; // /* was x=1; */ off-by-one bug corrected - pmg
在vi编辑器中无法使用(抛出“模式未找到://(.*)”),哈希(#)是干什么用的? - N 1.1
2
@N 1.1:哈希只是一个占位符,可以是任何字符。通常是正斜杠,但当您的模式中有斜杠时,使用不同的分隔符比转义所有斜杠更容易。s/foo/bar/ 等同于 s#foo#bar#sXfooXbarXs,foo,bar, 等。 - Adam Rosenfield
2
@N 1.1:在vi中,我认为你需要转义括号以捕获它们(未转义的情况下它们与文本匹配):s#//\\(.*\\)#/*\1 */#。'#'用于分隔搜索和替换(通常使用'/'进行替换,但使用'#'可以替换不需要转义'/'的情况)。 - pmg
1
@N 1.1:vi中搜索和替换的默认分隔符是“/”,但实际上您可以使用任何字符。当搜索字符串包含“/”字符时这非常有用(否则您需要转义其使用)。在vi中,您需要转义“(”和“)”,因此最终您会得到: % s#//\\(.*\\)$#/*\1*/# - Martin York

5
如果您正在寻找更通用的东西,也可以使用源代码格式化工具来实现。对于C语言,我以前使用过uncrustify,效果还不错。可能还有其他工具,但我认为uncrustify可以使用cmt_cpp_to_c参数将C++风格的注释转换为C风格的注释。
配置可能有点令人生畏,但如果您只使用示例配置文件并仅更改您感兴趣的内容,则可能会实现您想要的效果。

1
这看起来是一个简单的问题,但要处理所有边缘情况却非常困难。简单的解决方案可以在sed中轻松实现:
  sed -e 'sX// *\(.*[^ ]\) *$X/* \1 */X' < oldfile > newfile

你可以根据需要进行调整:我让它吃掉了注释开头和结尾的所有空格。
这种方法无法处理嵌套旧式注释的新式注释(正如其他人所指出的那样)。它真正混乱的是带有双斜杠的字符串,它们不是注释,但如果不解析字符串,它们将被修改为注释。请检查这些情况:
egrep '//.*/[*]|".*//' oldfile

如果你遇到这些问题,它们需要手动修正。任何尝试在实际解析文件之前自动化处理它都会产生新的更复杂的边缘情况,虽然你可能会识别出一个适合你情况的 hack 模式。

1

嗯,1,$s#//\(.*\)#/*\1 */# 只有在您的 C 代码中没有 C++ 风格注释实例(通常是多行)时才有效,因为替换将会过早地结束 C 风格注释,使剩余部分的 C 风格注释没有起始 /*

任何具有 */ 的常规 C++ 风格注释也会导致问题。这种情况发生在一个糟糕的程序员将 C 风格注释更改为 C++ 风格注释但未删除结尾的 */ 的代码中。


1

不幸的是,大多数脚本只能反向工作。有一个不错的叫做“RECOMMENT”的脚本,但它需要使用C语言并将其转换为更新的C++风格注释。我想你想要这样做的原因是由于使用C++风格注释时出现编译器错误。通常造成这种情况的原因是一行代码同时使用了C风格注释和C++风格注释。也许寻找特定的场景可以消除您将其转换回旧的注释风格的需求。如果不行,那么您可能不得不手动完成它。(我祈祷您不必这样做,因为我知道那会很繁琐!)


Recomment链接: http://people.sc.fsu.edu/~jburkardt/cpp_src/recomment/recomment.html


我会记住这个,等到需要的时候再用。你可能想在回答中提供一个RECOMMENT的链接。 - user191776
1
反过来做这件事的脚本很可怕。/* foo */ bar ++; 如果不改变行号,就无法正确翻译。 - nategoose
非常抱歉忘记链接了!我已经在答案底部更新了链接! - D.R.

1
你可以使用 Vim 插件 Nerdcommenter 来完成这个操作。
这使得取消注释和添加多行注释变得非常容易,就像你想要的那样。

1

Vim Nerdcommenter alternate delims map

如果你执行:<leader>ca,某些文件类型具有备用注释样式,特别是对于 C / C++,它允许在///*之间切换,在2.5.2中经过测试。

然后您可能还对使用<leader>cs的“性感注释模式”感兴趣,它可以像NERD commenter : How to comment out a range中提到的那样进行漂亮的 C 多行注释。


0

献给所有程序员!以下解决方案适用于Eclipse、Sublime和其他支持正则表达式的编辑器。

  1. 在Sublime中打开查找和替换
  2. 确保启用了正则表达式选项(Alt+R)
  3. 输入查找内容://(.*)
  4. 输入替换内容:/*\1 */

完成!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接