避免使用C++ 11原始字符串文字中的第一个换行符?

Hug*_*ues 23 c++ c++11

C++ 11中的原始字符串文字是非常好的,除了显示它们的明显方法导致冗余换行\n作为第一个字符.

考虑这个例子:

    some_code();
    std::string text = R"(
This is the first line.
This is the second line.
This is the third line.
)";
    more_code();
Run Code Online (Sandbox Code Playgroud)

明显的解决方法看起来很难看:

    some_code();
    std::string text = R"(This is the first line.
This is the second line.
This is the third line.
)";
    more_code();
Run Code Online (Sandbox Code Playgroud)

有没有人找到一个优雅的解决方案?

Ton*_*roy 23

您可以通过向const char*字符串文字自动转换到的内容添加1来获取指向第二个字符的指针 - 跳过前导换行符:

    some_code();
    std::string text = 1 + R"(
This is the first line.
This is the second line.
This is the third line.
)";
    more_code();
Run Code Online (Sandbox Code Playgroud)

恕我直言,以上是打破周围代码缩进的缺陷.有些语言提供了内置函数或库函数,它们可以执行以下操作:

  • 删除一个空的前导线,和
  • 查看第二行的缩进并从所有其他行中删除相同数量的缩进

允许使用如下:

some_code();
std::string text = unindent(R"(
    This is the first line.
    This is the second line.
    This is the third line.
    )");
more_code();
Run Code Online (Sandbox Code Playgroud)

编写一个在运行时运行的程序相对简单(参见ideone.com运行)...

std::string unindent(const char* p)
{
    std::string result;
    if (p[0] == '\n') ++p;
    const char* p_leading = p;
    while (std::isspace(*p) && *p != '\n')
        ++p;
    size_t leading_len = p - p_leading;
    while (*p)
    {
        result += *p;
        if (*p == '\n')
        {
            ++p;
            for (size_t i = 0; i < leading_len; ++i)
                if (p[i] != p_leading[i])
                    goto dont_skip_leading;
            p += leading_len;
        }
        else
            ++p;
      dont_skip_leading: ;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

...但是在编译时进行处理会好得多.我偶然发现这篇文章提到了一个"constexpr_string"库,它说明了类似的功能,但还没有解决它......

  • 是1个字符吗?还是2? (2认同)
  • 我真的只是提出一个话题。我们确定只有一个换行符吗?那有保证吗?还是取决于源文件的编码?如果是后者,那么您的 [第一个] 解决方案太乐观了。 (2认同)

Bri*_*ian 6

这可能不是您想要的,但为了以防万一,您应该注意自动字符串文字连接:

    std::string text =
"This is the first line.\n"
"This is the second line.\n"
"This is the third line.\n";
Run Code Online (Sandbox Code Playgroud)

  • 为什么不缩进呢?;) (6认同)
  • 请注意,它也适用于原始文字,因此 `R"(...)\n"` `R"(...)\n"` ... 也是一种可能性。 (3认同)
  • @马蒂厄M。看来您打算将 `\n` 放在那里并将其编码到实际的字符串中。 (3认同)
  • @Potatoswatter:啊!是的,确实,`\n` 应该被解释,所以 `R"(...)""\n"` `R"(...)""\n"` ... (3认同)