左填充用s.insert(0, n, c),右填充用s.append(n, c),n为max(0, width−s.length());width小于原长时应截断或忽略,不可盲目补位。

用 std::string 的 insert() 和 append() 手动实现左/右填充
标准 C++ 没有内置的 ljust 或 rjust,但靠 insert() 和 append() 能快速补位。关键不是“怎么写”,而是“填什么、填多少、填在哪”。
左填充本质是在开头插入字符;右填充是末尾追加。注意:目标长度小于原字符串时,多数场景应直接截断或忽略,而不是报错——这点容易被忽略,实际使用中要主动判断。
- 左填充:
s.insert(0, n, c),其中n = std::max(0, width - static_cast<int>(s.length()))</int> - 右填充:
s.append(n, c),同样先算出需补数量n - 若
width ,不做任何操作(除非你明确需要截断)
用 std::ostringstream + std::setw / std::setfill 做格式化填充
这是最接近 Python str.ljust() 的惯用法,适合输出场景(比如日志对齐、表格打印),但不适用于原地修改字符串变量。
它依赖流操作符,std::setw 只对下一个输出项生效,std::setfill 会持续作用直到被重置。常见错误是忘了重置填充字符,导致后续输出也被影响。
- 右填充示例:
std::ostringstream oss; oss
- 左填充需配合
std::left:oss.str(""); oss -
std::setw不会截断,超长内容照常输出,所以不能替代截断逻辑
封装成可复用函数时要注意的边界和类型问题
自己写 lpad() / rpad() 函数时,最容易踩的坑是参数类型和符号混淆:std::string::size_type 是无符号,直接减可能溢出;width 用 int 更安全,但需显式转换。
另一个问题是填充字符类型:只接受 char 还是也支持 std::string?多数简单场景用单字符就够了,强行支持多字符填充反而增加复杂度且易出错。
- 推荐签名:
std::string lpad(const std::string& s, int width, char fill = ' ') - 计算补长必须用
std::max(0, width - static_cast<int>(s.size()))</int>,避免无符号减法绕回 - 返回新字符串(不要传引用修改原串),语义更清晰,也避免意外副作用
第三方库如 absl::StrCat 或 fmt::format 怎么用
如果你项目已引入 fmt 库,直接用 fmt::format("{:0>10}", "abc")(右填充 0 到 10 位)或 fmt::format("{:*(左填充 *)最省事。它语法和 Python f-string 高度一致,且线程安全、零开销。
但注意:absl::StrCat 本身不提供填充功能,得组合 absl::string_view 和手动拼接;而 fmt 的填充语法在编译期检查格式串,写错会直接编译失败,比运行时才发现更早暴露问题。
- 右填充:
fmt::format("{:->10}", "x")→"---------x" - 左填充:
fmt::format("{:- → <code>"x---------" - 居中填充:
fmt::format("{:-^10}", "x")→"----x-----"
真正麻烦的从来不是“怎么填”,而是“填完要不要 trim”、“宽度是字节数还是字符数”、“Unicode 字符怎么算宽度”。这些在 C++ 里没标准答案,得按实际场景自己定规则。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











