C++23 格式化输出新特性详解: std::print 和 std::println

文章目录

    • 背景介绍
    • 主要特性
      • [1. 格式化字符串支持](#1. 格式化字符串支持)
      • [2. 简化输出操作](#2. 简化输出操作)
      • [3. 高性能实现](#3. 高性能实现)
    • 基本用法
      • [1. 使用 `std::print`](#1. 使用 std::print)
      • [2. 使用 `std::println`](#2. 使用 std::println)
    • 格式化选项
      • [1. 基本占位符](#1. 基本占位符)
      • [2. 对齐与填充](#2. 对齐与填充)
      • [3. 数值格式](#3. 数值格式)
      • [4. 浮点数格式](#4. 浮点数格式)
      • [2. 自定义类型格式化](#2. 自定义类型格式化)
    • 对容器的支持
    • 总结
    • 源码链接

C++23 带来了两个令人兴奋的新输出功能------std::print 和 std::println, 它们极大地简化了格式化输出操作, 同时保持了 C++ 一贯的高性能和灵活性. 本文将详细介绍这些新特性, 探讨其实际用法, 并通过代码示例展示如何在实际项目中使用它们.


背景介绍

在传统 C++ 中, 格式化输出通常依赖于 std::cout 或 printf. std::cout 虽然灵活但语法冗长, printf 虽然简洁但类型安全性较差. 为了简化输出操作并提高可读性, C++20 引入了 std::format, C++23 更进一步, 将其与输出流结合, 推出了 std::print 和 std::println.

这些特性不仅让 C++ 输出更接近 Python 的 print, 还兼具高性能和类型安全, 完美平衡了易用性和功能强大性.


主要特性

1. 格式化字符串支持

  • 基于 C++20 的 std::format, 使用花括号 {} 作为占位符.
  • 支持自动类型推断, 提供丰富的格式化选项, 如对齐, 填充, 精度设置等.

2. 简化输出操作

  • std::print : 直接输出内容到标准输出(类似 std::cout).
  • std::println : std::print 的换行版本, 自动在输出后添加换行符.

3. 高性能实现

  • 输出效率高, 避免了额外的中间缓冲.
  • 直接格式化到输出流, 减少了运行时开销.

基本用法

1. 使用 std::print

以下示例展示如何使用 std::print 输出格式化内容:

cpp 复制代码
#include <print>

int main() {
  std::print("Hello, {}!\n", "World");    // 输出: Hello, World!
  std::print("The answer is: {}\n", 42);  // 输出: The answer is: 42
  return 0;
}

2. 使用 std::println

std::println 提供了更加简洁的换行输出功能:

cpp 复制代码
#include <print>

int main() {
  std::println(
      "This is a println example!");  // 输出: This is a println example!
  std::println("Value: {}, Pi: {:.2f}", 10,
               3.14159);  // 输出: Value: 10, Pi: 3.14
  return 0;
}

格式化选项

1. 基本占位符

使用花括号 {} 占位符, 可以轻松插入变量值:

cpp 复制代码
std::println("{} + {} = {}", 2, 3, 2 + 3);  // 输出: 2 + 3 = 5

2. 对齐与填充

对齐输出内容, 适合打印表格或报告:

cpp 复制代码
std::println("|{:>10}|", "right");   // 右对齐: |     right|
std::println("|{:<10}|", "left");    // 左对齐: |left      |
std::println("|{:^10}|", "center");  // 居中对齐: |  center  |
std::println("|{:-^10}|", "fill");   // 居中填充: |--fill---|

3. 数值格式

支持多种数值格式输出:

cpp 复制代码
std::println("Decimal: {}", 42);     // 十进制: Decimal: 42
std::println("Hex: {:#x}", 255);     // 十六进制: Hex: 0xff
std::println("Octal: {:#o}", 255);   // 八进制: Octal: 0377
std::println("Binary: {:#b}", 255);  // 二进制: Binary: 0b11111111
std::println("Padded: {:08}", 42);   // 填充: Padded: 00000042

4. 浮点数格式

打印浮点数时, 可指定精度和宽度:

cpp 复制代码
std::println("Default    : {}", 3.14159);       // 默认: 3.14159
std::println("Fixed      : {:.2f}", 3.14159);   // 保留两位小数: 3.14
std::println("Scientific : {:.2e}", 3.14159);   // 科学计数法: 3.14e+00
std::println("Width      : {:8.2f}", 3.14159);  // 宽度 8:     3.14

2. 自定义类型格式化

通过实现 std::formatter, 可以为自定义类型提供格式化支持:

cpp 复制代码
#include <format>
#include <print>
#include <string>

struct Point {
  int x, y;
};

template <>
struct std::formatter<Point> {
  constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
  auto format(const Point& p, std::format_context& ctx) const {
    return std::format_to(ctx.out(), "({}, {})", p.x, p.y);
  }
};

int main() {
  Point p{3, 4};
  std::println("Point: {}", p);  // Output: Point: (3, 4)
  return 0;
}

对容器的支持

std::print 和 std::println 暂不支持直接打印容器, 如 std::vector 或 std::map. 此时可以借助第三方库 libfmt, 例如:

cpp 复制代码
#include <fmt/core.h>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    fmt::print("Vector: [{}]\n", fmt::join(vec, ", "));
    return 0;
}

总结

C++23 的 std::print 和 std::println 为开发者提供了现代化, 简洁且高效的格式化输出工具. 它们不仅让代码更易于书写和阅读, 还极大地提升了开发体验.

这些特性特别适合需要频繁格式化输出的场景, 如日志系统, 调试工具和数据报告. 如果您需要更复杂的功能, 可以借助 libfmt 等库扩展其应用范围.

源码链接

源码链接

相关推荐
布莱克60517 分钟前
C/C++ 中变量的声明与定义:区别、联系与常见误区
c语言·开发语言·c++·声明·定义
LabVIEW开发26 分钟前
LabVIEW 局部变量为何引发竞争条件?四种同步机制
开发语言·labview
benchmark_cc1 小时前
A 股、港股、美股如何建立统一的标的主数据格式?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
Zenova EdgeOS2 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
取名真是2 小时前
Python 算法知识点从基础到进阶
开发语言·python·算法
FRing033 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Fatbobman(东坡肘子)4 小时前
快速消失的硬盘容量 -- 肘子的 Swift 周报 #160
开发语言·人工智能·redis·ios·swiftui·iphone·swift
揽星河..4 小时前
【C语言】底层程序设计
c语言·开发语言
JavaPub-rodert4 小时前
从零搭建通用管理后台:ShiyuAdmin 的 Go、React 与 RBAC 实践
开发语言·react.js·golang
沫璃染墨5 小时前
从零入门计算机网络系列(十二):HTTP长连接与会话管理详解——从Connection到Cookie与Session
linux·服务器·c++·tcp/ip·ubuntu·http·交互