首页 > 解决方案 > 将内联注释的格式从 // 更改为 /* */

问题描述

我有一个包含多个以 // 开头的内联注释的 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 \*\//
现在这对我有用。

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

标签: regexsed

解决方案


编辑

请参阅这个比我的好得多的旧答案(也是用 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

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

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

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

针对这些问题的建议:

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

多行注释(或多行字符串文字,机器人是独角兽)的问题仍然存在,但也许您可以在其中找到另一种模式,例如 *在行首的 a 。无论如何,代码不会无效;只会在评论中发生一些不需要的更改。

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


推荐阅读