You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何去除C++多行raw string literals中的前导空格?

解决C++多行原始字符串字面量前导空格问题

你不想把字符串左移到代码最左侧破坏缩进格式,但又要移除输出中的前导空格,这里有几种实用方案:

方案一:编译时移除固定前缀空格(C++20+)

写一个constexpr函数,在编译阶段就处理掉每一行的固定数量前导空格,不影响运行效率,同时保持代码缩进:

#include <string>
#include <print>
#include <algorithm>
#include <ranges>

constexpr std::string_view trim_lines_prefix(std::string_view sv, std::size_t prefix_len) {
    std::string result;
    bool skip_first = true;
    for (auto line : sv | std::views::split('\n')) {
        if (skip_first) {
            skip_first = false;
            continue; // 跳过原始字符串开头的空行
        }
        // 移除对应长度的前导空格,长度不足则保留原内容
        if (line.size() >= prefix_len) {
            result += std::string_view(line.begin() + prefix_len, line.end());
        } else {
            result += std::string_view(line.begin(), line.end());
        }
        result += '\n';
    }
    if (!result.empty()) result.pop_back(); // 去掉最后多余的换行
    return std::string_view(result);
}

int main()
{
   constexpr auto preamble_raw =
      R"(
        <?xml version="1.0" encoding="iso-8859-1"?>
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="https://www.w3.org/1999/xhtml">
        <head>
           <meta name="Author" content="Some One" />
           <title>Title Of Page</title>
        </head>
        <body style="">
      )";

   // 这里的8是原始字符串每行的前导空格数,根据实际缩进调整
   constexpr auto preamble = trim_lines_prefix(preamble_raw, 8);

   std::println("{}", preamble);
   return 0;
}

方案二:预处理器宏自动适配缩进(兼容C++11+)

用宏自动识别第一行有效内容的前导空格数,批量移除所有行的对应空格,无需手动指定长度:

#include <string>
#include <print>

#define RAW_STR(...) #__VA_ARGS__

#define TRIMMED_RAW_STR(...) \
    []() { \
        std::string s = RAW_STR(__VA_ARGS__); \
        size_t prefix_len = s.find_first_not_of("\n \t"); \
        if (prefix_len == std::string::npos) return s; \
        size_t line_pos = 0; \
        while ((line_pos = s.find('\n', line_pos)) != std::string::npos) { \
            ++line_pos; \
            // 如果当前行开头有对应数量的空格,就移除
            if (s.substr(line_pos, prefix_len) == std::string(prefix_len, ' ')) { \
                s.erase(line_pos, prefix_len); \
            } \
        } \
        // 去掉开头的空白行和空格
        s.erase(0, s.find_first_not_of("\n \t")); \
        return s; \
    }()

int main()
{
   auto preamble = TRIMMED_RAW_STR(
        <?xml version="1.0" encoding="iso-8859-1"?>
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="https://www.w3.org/1999/xhtml">
        <head>
           <meta name="Author" content="Some One" />
           <title>Title Of Page</title>
        </head>
        <body style="">
    );

   std::println("{}", preamble);
   return 0;
}

这个宏会自动处理缩进,不管你在类方法还是嵌套命名空间里,代码的缩进格式都能保持原样。

方案三:C++23范围工具简化处理

如果你的项目已经用C++23,用std::views可以写出更简洁的代码:

#include <string>
#include <print>
#include <ranges>
#include <string>

int main()
{
   constexpr std::string_view preamble_raw =
      R"(
        <?xml version="1.0" encoding="iso-8859-1"?>
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="https://www.w3.org/1999/xhtml">
        <head>
           <meta name="Author" content="Some One" />
           <title>Title Of Page</title>
        </head>
        <body style="">
      )";

   auto trimmed = preamble_raw 
                  | std::views::drop(1) // 跳过开头的空行
                  | std::views::transform([](auto line) {
                      // 每行去掉前8个空格,根据实际缩进调整
                      return std::string_view(line).substr(8);
                    })
                  | std::views::join_with('\n');

   std::println("{}", std::string(trimmed));
   return 0;
}

内容的提问来源于stack exchange,提问作者Penny Dreudter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 00:20:13