C/C++字符串格式化全解析:从printf到std::format的安全演进与实战指南
目录
C 语言中的格式化函数对比
1. printf / fprintf / sprintf 的异同
C++ 中的字符串格式化
1. 流式输出 (std::ostringstream)
2. C++20/23 格式化库 (std::format,需编译器支持)
跨语言对比与最佳实践
实战建议
总结
C 语言中的格式化函数对比
1. printf
/ fprintf
/ sprintf
的异同
函数 | 输出目标 | 返回值 | 主要用途 |
---|---|---|---|
printf | 标准输出 (stdout ) | 写入的字符数 | 控制台输出 |
fprintf | 任意文件流 (FILE* ) | 写入的字符数 | 文件或日志写入 |
sprintf | 字符数组 (char[] ) | 写入的字符数 | 内存中构造字符串 |
代码示例:
#define _CRT_SECURE_NO_WARNINGS#include <iostream>#include <time.h>using namespace std;int main(){const int len = 128;time_t tx = time(nullptr);struct tm* p = localtime(&tx);char buff[len] = {};fprintf(stdout, "%4d/%02d/%02d/-%02d:%02d:%d\n", p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);sprintf(buff, "%4d/%02d/%02d/-%02d:%02d:%d\n",p->tm_year + 1900, p->tm_mon + 1,p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);cout << buff << endl;return 0;}
关键风险: sprintf
无缓冲区越界检查,若格式化后的字符串长度超过 buff
的大小会导致缓冲区溢出。 ✅ 安全改进: 使用 snprintf
指定最大写入长度:
snprintf(buff, len, "..."); // 保证不超过 len-1 字节
C++ 中的字符串格式化
1. 流式输出 (std::ostringstream
)
核心优势:
-
类型安全:无需手动匹配格式符(如
%d
vs%s
) -
内存安全:自动管理缓冲区,无需预分配固定大小
-
扩展性:支持自定义类型的
operator<<
重载
代码示例:
#define _CRT_SECURE_NO_WARNINGS#include <iostream>#include <time.h>#include <sstream>using namespace std;int main() {time_t tx = time(nullptr);struct tm *tmbuf = localtime(&tx);ostringstream oss;oss << (tmbuf->tm_year + 1900) << "/"<< (tmbuf->tm_mon + 1) << "/"<< tmbuf->tm_mday << " "<< tmbuf->tm_hour << ":"<< tmbuf->tm_min << ":"<< tmbuf->tm_sec;string datetime = oss.str();cout << datetime << endl;return 0;}
2. C++20/23 格式化库 (std::format
,需编译器支持)
#include <format>int main() {int year = 2024, month = 7, day = 17;auto str = format("{:04}/{:02}/{:02}", year, month, day);// 输出 "2024/07/17"return 0;}
特点:
-
类似 Python 的
str.format
语法 -
编译时格式字符串检查(C++20 起支持
consteval
) -
高性能且类型安全
跨语言对比与最佳实践
特性 | C (sprintf ) | C++ (ostringstream ) | C++20 (std::format ) |
---|---|---|---|
类型安全 | ❌ 易出错 | ✅ 安全 | ✅ 安全 |
缓冲区溢出风险 | ❌ 高风险 | ✅ 无 | ✅ 无 |
格式化灵活性 | ✅ 高 | ⚠️ 中等(需手动填充) | ✅ 高 |
性能 | ✅ 高 | ⚠️ 中等 | ✅ 高 |
代码可读性 | ❌ 低 | ✅ 高 | ✅ 高 |
实战建议
-
C 语言场景
-
始终优先使用
snprintf
而非sprintf
-
检查返回值以确认实际写入长度:
if (n >= len) { /* 处理截断 */ }
-
-
C++ 场景
-
通用场景:使用
std::ostringstream
,适合简单拼接和类型安全需求 -
高性能/复杂格式化:使用
std::format
(需 C++20) -
旧代码兼容:可封装
snprintf
到std::string
:string format(const char* fmt, ...) {char buf[1024];va_list args;va_start(args, fmt);vsnprintf(buf, sizeof(buf), fmt, args);va_end(args);return buf;}
-
-
时间格式化专用工具 C++11 起可使用
<chrono>
+std::put_time
:#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <sstream> #include <iomanip> #include <chrono> using namespace std; int main() {auto now = chrono::system_clock::now();time_t t = chrono::system_clock::to_time_t(now);ostringstream oss;oss << put_time(localtime(&t), "%Y/%m/%d %H:%M:%S");string datetime = oss.str();cout << datetime << endl;return 0; }
总结
-
C 语言:用
snprintf
替代sprintf
,并严格检查缓冲区大小 -
C++ 旧标准:
std::ostringstream
提供安全但稍显冗长的格式化 -
C++20+:
std::format
是兼顾性能、安全与可读性的终极方案 -
时间处理:优先使用
<chrono>
和std::put_time
避免手动计算
相关文章:
C/C++字符串格式化全解析:从printf到std::format的安全演进与实战指南
目录 C 语言中的格式化函数对比 1. printf / fprintf / sprintf 的异同 C 中的字符串格式化 1. 流式输出 (std::ostringstream) 2. C20/23 格式化库 (std::format,需编译器支持) 跨语言对比与最佳实践 实战建议 总结 C 语言中的格式化函数对比 1. printf / …...

【C++】stack 和 queue 的适配器模式与实现
> 🍃 本系列为初阶C的内容,如果感兴趣,欢迎订阅🚩 > 🎊个人主页:[小编的个人主页])小编的个人主页 > 🎀 🎉欢迎大家点赞👍收藏⭐文章 > ✌️ 🤞 …...

【python】You-Get
文章目录 1、介绍2、安装与使用文档3、下载图片4、下载视频5、下载音乐6、参考 1、介绍 You-Get is a tiny command-line utility to download media contents (videos, audios, images) from the Web, in case there is no other handy way to do it. 源码:https…...

PHP基础部分
但凡是和输入、写入相关的一定要预防别人植入恶意代码! HTML部分 语句格式 <br> <hr> 分割符 <p>插入一行 按住shift 输入! 然后按回车可快速输入html代码(VsCode需要先安装live server插件) html:<h1>标题 数字越大越往后</h1> <p…...

gitee SSH 公钥设置教程
Gitee 提供了基于 SSH 协议的 Git 服务,在使用 SSH 协议访问仓库仓库之前,需要先配置好账户 SSH 公钥。 1、生成秘钥 Windows 用户建议使用 Windows PowerShell 或者 Git Bash,在 命令提示符 下无 cat 和 ls 命令。 ssh-keygen -t ed25519 -C "Gitee SSH Key"中间…...

Java零基础入门笔记:(3)程序控制
前言 本笔记是学习狂神的java教程,建议配合视频,学习体验更佳。 【狂神说Java】Java零基础学习视频通俗易懂_哔哩哔哩_bilibili Scanner对象 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类&…...
鸡兔同笼问题
鸡兔同笼问题是这样一个问题: 现有鸡、兔合装在一个笼子里。数头一共100个头,数脚一共300只脚。问有多少只鸡多少只兔? 在这里讨论这个问题的解法当然太小儿科了。但是y_tab这个C语言解释器只提供了1维数组。如果需要用到2维数组时ÿ…...

【Pytorch 库】自定义数据集相关的类
torch.utils.data.Dataset 类torch.utils.data.DataLoader 类自定义数据集示例1. 自定义 Dataset 类2. 在其他 .py 文件中引用和使用该自定义 Dataset torch_geometric.data.Dataset 类torch_geometric.data.Dataset VS torch.utils.data.Dataset 详细信息,参阅 tor…...

electron打包基本教程
从0开始搭建 概要步骤基础软件运行项目打包项目 注意事项 概要 将html打包成桌面的主流有electron和nwjs,nwjs更加简单,但是使用效果不如electron,electron打包比较麻烦,但是效果比较好,反正各有优势和缺点 步骤 基…...

实现pytorch注意力机制-one demo
主要组成部分: 1. 定义注意力层: 定义一个Attention_Layer类,接受两个参数:hidden_dim(隐藏层维度)和is_bi_rnn(是否是双向RNN)。 2. 定义前向传播: 定义了注意力层的…...
深入Flask:如何优雅地处理HTTP请求与响应
哈喽,大家好,我是木头左! 本文将带你深入了解如何在Flask中优雅地处理HTTP请求和响应,让你的应用更加高效、安全和用户友好。 创建一个简单的Flask应用 让从创建一个最简单的Flask应用开始: from flask import Flaskapp = Flask(__name__)@app.route(/) def...

JVM ②-双亲委派模型 || 垃圾回收GC
这里是Themberfue 在上节课对内存区域划分以及类加载的过程有了简单的了解后,我们再了解其他两个较为重要的机制,这些都是面试中常考的知识点,有必要的话建议背出来,当然不是死记硬背,而是要有理解的背~~~如果对 JVM …...
jQuery介绍(快速、简洁JavaScript库,诞生于2006年,主要目标是简化HTML文档操作、事件处理、动画和Ajax交互)
文章目录 **核心功能 & 亮点**1. **简化 DOM 操作**2. **链式调用**3. **跨浏览器兼容**4. **便捷的事件绑定**5. **Ajax 封装**6. **动画效果** **现状与适用场景**- **传统项目维护**:许多旧系统(如 WordPress 插件、老企业网站)仍依赖…...

python旅游推荐系统+爬虫+可视化(协同过滤算法)
✅️基于用户的协同过滤算法 ✅️有后台管理 ✅️2w多数据集 这个旅游数据分析推荐系统采用了Python语言、Django框架、MySQL数据库、requests库进行网络爬虫开发、机器学习中的协同过滤算法、ECharts数据可视化技术,以实现从网站抓取旅游数据、个性化推荐和直观展…...

Ubuntu 22.04.5 LTS 安装企业微信,(2025-02-17安装可行)
一、依赖包(Ubuntu 20.04/Debian 11) 点击下载https://www.spark-app.store/download_dependencies_latest 1、 下载最新的依赖包。 请访问星火应用商店依赖包下载页面, 下载最新的依赖包。2、解压依赖包 </...
【Excel笔记_6】条件格式和自定义格式设置表中数值超过100保留1位,超过1000保留0位,低于100为默认
方法一:自定义格式 选中需要设置格式的单元格区域。右键选择设置单元格格式,或者在工具栏中选择开始 -> 数字 -> 自定义格式。在类型框中输入以下自定义格式: [>1000]0;[>100]0.0;G/通用格式解释: [>1000]0&…...

UDP与TCP
用UDP一定比用TCP快吗? 假设我们需要在a电脑的进程发一段数据到b电脑的进程我们可以选择使用TCP或UDP协议进行通信。 对于TCP这样的可靠性协议每次消息发出后都能明确知道对方有没有收到,就像打电话一样,只要“喂喂"两下对方就能回你个…...

Web开发技术概述
Web开发技术涵盖了前端和后端开发,以及数据库技术。前端开发包括使用HTML、CSS、JavaScript等原生技术,以及jQuery、Bootstrap、AngularJS、React、Vue等框架。后端开发则涉及ASP.NET、PHP、Python Web(Flask、Django)、Java Web&…...

解压rar格式的软件有哪些?8种方法(Win/Mac/手机/网页端)
RAR 文件是一种常见的压缩文件格式,由尤金・罗谢尔(Eugene Roshal)开发,因其扩展名 “rar” 而得名。它通过特定算法将一个或多个文件、文件夹进行压缩,大幅减小存储空间,方便数据传输与备份。然而…...

uniapp开发:首次进入 App 弹出隐私协议窗口
前言:在移动应用开发中,隐私协议弹窗是一个非常重要的功能。它不仅符合法律法规的要求(如 GDPR、CCPA 等),还能增强用户对 App 的信任感。本文将介绍如何在 Uniapp 开发的 App 中实现“首次进入弹出隐私协议窗口&#…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...