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

如何使用fmtlib保留多行字符串的缩进格式?

使用fmtlib为多行字符串添加统一缩进的解决方案

问题场景

你在使用fmtlib格式化自动生成代码时,遇到了多行字符串参数无法继承格式字符串中指定缩进的问题。示例代码如下:

auto str = fmt::format(
  "{header}\n"
  "  {body}\n"
  "{footer}",
  fmt::var("header", single_line_str()),
  fmt::var("body", multi_line_str()),
  fmt::var("footer", single_line_str()) 
);

当body为以下多行内容时:

The quick brown
fox jumped over
the lazy dog

实际输出仅第一行带有缩进:

begin
  The quick brown
fox jumped over
the lazy dog
end

但你需要body的每一行都自动带上格式字符串中指定的 缩进,同时嵌套场景下支持相对缩进(而非硬编码绝对缩进)。


解决方案

可以通过自定义辅助函数或fmtlib格式化器实现,以下是两种实用方案:

方案1:直接使用辅助函数处理多行字符串

定义一个工具函数,给多行字符串的每一行(除第一行外)添加指定缩进:

#include <sstream>
#include <string>

std::string indent_multiline(const std::string& input, const std::string& indent) {
  std::ostringstream oss;
  std::istringstream iss(input);
  std::string line;
  bool is_first_line = true;

  while (std::getline(iss, line)) {
    if (!is_first_line) {
      oss << '\n' << indent;
    }
    oss << line;
    is_first_line = false;
  }

  return oss.str();
}

修改原代码,在传入body参数时调用该函数:

auto str = fmt::format(
  "{header}\n"
  "  {body}\n"
  "{footer}",
  fmt::var("header", single_line_str()),
  fmt::var("body", indent_multiline(multi_line_str(), "  ")),
  fmt::var("footer", single_line_str()) 
);

方案2:自定义fmtlib格式化器(更适合嵌套场景)

如果需要频繁处理这类多行缩进需求,或要支持灵活的嵌套相对缩进,可以定义一个包装结构体并实现fmt格式化器:

#include <fmt/core.h>
#include <sstream>
#include <string>

// 包装多行字符串和对应的缩进
struct indented_multiline {
  std::string content;
  std::string indent;
};

// 为indented_multiline实现fmt格式化逻辑
template <>
struct fmt::formatter<indented_multiline> : fmt::formatter<std::string> {
  template <typename FormatContext>
  auto format(const indented_multiline& im, FormatContext& ctx) {
    std::ostringstream oss;
    std::istringstream iss(im.content);
    std::string line;
    bool is_first_line = true;

    while (std::getline(iss, line)) {
      if (!is_first_line) {
        oss << '\n' << im.indent;
      }
      oss << line;
      is_first_line = false;
    }

    return fmt::formatter<std::string>::format(oss.str(), ctx);
  }
};

使用时直接传递包装后的对象,嵌套场景下只需传递对应层级的缩进即可:

// 外层缩进
auto outer_str = fmt::format(
  "{header}\n"
  "  {}\n"
  "{footer}",
  single_line_str(),
  indented_multiline{multi_line_str(), "  "},
  single_line_str() 
);

// 嵌套场景:内层在基础缩进上再加两个空格
auto nested_str = fmt::format(
  "outer_begin\n"
  "  {}\n"
  "outer_end",
  indented_multiline{get_nested_multi_line_str(), "    "}
);

内容的提问来源于stack exchange,提问作者Jonah F

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:25:14