【问题标题】:Reformat C++ braces without changing indentation?在不改变缩进的情况下重新格式化 C++ 大括号?
【发布时间】:2009-06-12 12:12:17
【问题描述】:

我们想让我们的 C++ 大括号样式更加一致。现在,我们的代码包含以下内容:

if (cond)
{
    // ...    
}
else
{
    // ...
}

...和:

if (cond) {
    // ...
} else {
    // ...
}

我们想专门使用后一种风格。

但是,我们想要更改代码的缩进。我尝试过使用 astyle、bcpp、GNU indent 和 Uncrustify(我还查看了 GreatCode 的命令行选项)。不幸的是,这些工具中的每一个都坚持重新缩进我们的代码,并且其中大多数都非常糟糕地破坏了 C++ 构造函数初始化器列表和预处理器宏。

是否有任何 C++ 代码美化器可以修复大括号,同时保留缩进?它不必是一个预先存在的工具——如果你知道如何使用一些疯狂的 Perl 单线来做到这一点,那也很好。谢谢!

更新: 是的,我们知道这会导致难以阅读与旧代码的差异。这是一项推迟已久的代码清理工作,我们认为一致格式的日常优势胜过任何版本控制困难。

【问题讨论】:

  • 你们这些小东西都汗流浃背了。

标签: c++ formatting coding-style indentation curly-braces


【解决方案1】:

这是一个 Perl 单行代码,应该可以满足您的需求。

perl -pi.bak -e 'BEGIN { undef $/; } s/\s*?(\s?\/\/.*)?\r?\n\s*{/ {\1/g; s/}(\s?\/\/.*)?\r?\n\s*else\b(.*)/} else\2\1/g;'

原来是这样的:

int main(int argc, char *argv[])
{
    int something = 0;
    if (something)    // 5-12-2007
    {
        printf("Hi!\n");
    }
    else   // 5-13-2007
    {
        printf("Bye\n");
    }
    return 0;
}

进入这个:

int main(int argc, char *argv[]) {
    int something = 0;
    if (something) { // 5-12-2007
        printf("Hi!\n");
    } else { // 5-13-2007
        printf("Bye\n");
    }
    return 0;
}

【讨论】:

  • 太棒了!我会在一个小时左右试试这个。
  • 非常感谢!这是一个好的开始,它可以适应处理其他结构,如“catch”。
【解决方案2】:

在执行此操作之前,您确实应该三思而后行。它将在更改点完全破坏您的源代码控制系统的修订历史。您正在使用源代码控制系统,不是吗?

【讨论】:

  • 也许我太厚了,但我不明白。我看到的唯一问题是更改前后的文件差异会导致很多差异。我不明白“它将如何彻底破坏您的源代码控制系统的修订历史”。
  • 准确地说 - 有很多差异 - 如果使用的是短方法,可能每隔一行。这将使差异变得无用 - 您将无法从重新格式化引起的噪音中找出真正的变化。
  • 嗯,你是对的。它不会完全破坏您的修订历史。它只会破坏您将受影响的新代码与更改边界上的旧代码进行比较的能力。这可能对您或您的项目很重要,也可能无关紧要。
  • 我们已经在这种不一致的格式中生活了 7 年多,我们已经决定我们可以负担一个十年一次的标志日,让我们的代码更容易被破解。 :-) 所有优秀的分支都已合并,我们并不关心我们越来越古老的稳定分支。
  • 如果你已经使用了 7 年以上,我看不出你为什么会改变。这并不是说您要改变的风格是一种特别糟糕或不常见的风格。
【解决方案3】:
perl -ei '$/=undef;while(<>){s/}\s*?(\s*\/\/^[\r\n]*)?\r?\n\s*else/} else$1/gm;s/(\s*\/\/[^\r\n]*)?\r?\n\s*{/ {$1/gm;print;}' yoursourcefile.cpp

这首先将} &lt;eol&gt; &lt;whitespace&gt; else 转换为} else,然后从&lt;eol&gt; &lt;whitespace&gt; { 中删除行尾。

要将其应用于源树,请使用 findxargs

find . -name \*.cpp -print0 | xargs -0 perl -ei '$/=undef;while(<>){s/}\s*?(\s*\/\/^[\r\n]*)?\r?\n\s*else/} else$1/gm;s/(\s*\/\/[^\r\n]*)?\r?\n\s*{/ {$1/gm;print;}'

【讨论】:

    【解决方案4】:

    UNIX 命令 Indent (http://en.wikipedia.org/wiki/Indent_(Unix))(适用于 GNU 的 PC)具有一百万个选项,可以完全按照您的喜好自定义重新格式化。

    【讨论】:

    • 据我所知,大多数缩进命令总是重新缩进源代码,就像所有其他工具一样。你知道有什么方法可以关闭它吗?另外,缩进一般不支持 C++。
    • 如果您可以 (1) 指出带有必要选项的缩进版本,并且 (2) 解释手册中不明显的任何内容,那么我会接受这个答案。但是我已经花了半个小时看 GNU 缩进,没有运气。
    【解决方案5】:

    难道没有一手简单的正则表达式就可以解决问题吗?像 (\).?\n.?\{) -> (\) \{) 删除右括号和左大括号之间的空格。

    【讨论】:

      【解决方案6】:

      我过去曾解决过类似的问题,首先运行 astyle 之类的工具来完成我们想要的 95%,然后在结果上编写 Perl 或 Python 脚本来完成剩下的 5%。试试看,了解你的正则表达式总是一个好习惯。 :)

      【讨论】:

        猜你喜欢
        • 2015-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        相关资源
        最近更新 更多