【问题标题】:Change formatting of inline comments from // to /* */ [closed]将内联注释的格式从 // 更改为 /* */ [关闭]
【发布时间】:2019-10-01 03:52:03
【问题描述】:

我有一个包含多个以 //.
开头的内联 cmets 的 C 文件 例如,

    u32 Status;                                                              

    // Read foo peripherals status                                   
    Status =  foo_periph_status(foo_Instance);

    // Check if foo is ready to turn right                                  
    if ((Status) & (FOO_STATUS_TURN_RIGHT_MASK)) {                          

        // Get FOO current state                                            
        foo_Instance->CurrentState = Foo_GetCurrentState(incoming_data);

        // Get FOO format                                                   
        foo_Instance->CurrentState.metadata.Format = Foo_GetFormat(incoming_data)  

在上面的代码中,我想将所有 // inline comments 从它们当前的格式更改为 /* Inline comments */ 格式。

我试过用,
s/\([^.*]\)\(\/\/\)\(.*\)\($\)/\1\/\*\3 \*\//
现在这对我有用。

我想知道是否有更好的方法来做到这一点?

标签: regex sed


【解决方案1】:

编辑

请参阅这个比我的好得多的旧答案(也是用 C 编写的):https://stackoverflow.com/a/12000755/6872717


#include <stddef.h>
#include <stdio.h>
#include <string.h>


#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define ARRAY_SSIZE(arr) ((ptrdiff_t)ARRAY_SIZE(arr))


// Read line from file
fgets(buff, BUFSIZ, fp_r);

// Find "//" comment
p = strstr(buff, "//");
if (!p)
        continue;

// If comment is at the very end of the buffer, and wouldn't fit, remove it.
if ((p - &buff[0] + strlen("/**/\n") + 1) > ARRAY_SSIZE(buff)) {
        sprintf(p, "\n");
        continue;
}

// Remove "*/" that would break the new comment format
do {
        q = strstr(p, "*/");
        if (q)
                memmove(q, q + strlen("*/"), strlen(q + strlen("*/")) + 1);
} while (q);

// Write the new comment begining
sprintf(p, "/*");

// Find end of line
p = strrchr(buff, '\n');

// Check that the closing "*/" fits in the buffer
while ((p - &buff[0] + strlen("*/\n") + 1) > ARRAY_SSIZE(buff))
        p--;

// Write closing "*/"
sprintf(p, "*/\n");

// Write line to file
fputs(buff, fp_w);

这将修复一条线。您只需要添加代码即可遍历整个文件。您需要打开两个文件:您正在读取的文件 (fp_r) 和一个新文件 (fp_w)。您必须删除旧文件,并在删除第一个文件后用相同的名称重命名新文件,这样结果就是一个被覆盖的文件。

这将删除// 之后出现的所有*/

问题:

  • 它不会处理以“/**/”格式编写的注释并且其中包含// 的情况,因为它不太可能且难以解决(参见以下示例)。如果发生这种情况,结果可能是无效注释。 示例:
a = 7; /* // this will mess everything */
a = /*7*/b; /* // hello, this too */ c=a; // another comment

那是单行的,而且已经很复杂了。想象一下在多行 cmets 中处理它......

  • 如果在字符串文字中找到//,则会发生与上述相同的情况。它有类似的困难,而且也不太可能,所以我不会费心解决它;如果您需要,这取决于您:)。结果也将是无效代码 (感谢@EdMorton 发现了这个)。

  • 如果注释太长以至于在缓冲区末尾附近结束,它将截断一行。但是,生成的评论将是有效的。

针对这些问题的建议:

如果在将要修改的行中检测到 /**/",则提示用户,然后再将其实际写入文件,向他显示原始和修改(您需要保留原件的副本),让他决定是喜欢旧线路还是新线路。并让用户在完成大部分工作后手动修改这些行;-)

多行 cmets(或多行字符串文字,机器人是独角兽)的问题仍然存在,但也许你可以在其中找到另一种模式,例如在行的开头 * .无论如何,代码不会无效;只是在 cmets 内部会发生一些不需要的变化。

另一种解决方案可能是在每次更改时提示用户。

【讨论】:

  • 这真的是 C 中这个问题的解决方案吗? :)
  • @AlexHarvey 是的。虽然我对 shell 有一些了解,但当事情开始变得复杂时,例如在这种情况下,对我来说 C 是最简单的解决方案 :)
  • 我想有时适合这项工作的工具是 C,因为你真的非常非常了解它。 ;-)
  • 此类任务的另一个常见问题是处理字符串中的匹配字符串,例如printf("hello // world\n");。我假设这对您的代码来说也是一个问题。我还想知道您的Remove "*/" ... 代码在各种情况下如何处理printf("hello */ world\n");。无论如何,OP都在自找麻烦.... :-)。实际上,我很惊讶某些 C 美化器无法选择将 //-style 转换为 /*..*/-style cmets 以输出 K&R 风格的代码,但快速谷歌并没有产生任何结果。
  • @EdMorton 没错,我没有考虑字符串文字,我会将其添加到答案中的警告中。 */ 的删除仅从“//”右侧开始,因此只会影响 cmets(或异常)。
猜你喜欢
  • 2021-12-21
  • 2021-08-14
  • 2016-01-26
  • 1970-01-01
  • 2012-06-07
  • 2011-06-28
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
相关资源
最近更新 更多