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)
核心优势:
-
类型安全:无需手动匹配格式符(如
%dvs%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 中实现“首次进入弹出隐私协议窗口&#…...
taotoken 多模型聚合能力如何赋能智能客服场景开发
Taotoken 多模型聚合能力在智能客服场景的开发实践 1. 智能客服场景的模型需求特点 智能客服系统需要处理多样化的用户咨询场景,从简单的FAQ问答到复杂的业务逻辑解析。不同场景对语言模型的要求存在显著差异。例如产品参数查询需要精确的事实检索能力,…...
多模态模型理解与生成能力差距量化研究
1. 多模态模型能力差距研究的背景与意义在人工智能领域,多模态模型(Unified Multimodal Models, UMMs)已经成为当前研究的热点方向。这类模型能够同时处理和理解来自不同模态的信息,如文本、图像、音频等,并在这些模态之间建立关联。然而&…...
KEIL Map文件实战:如何从内存分布图揪出栈溢出元凶(附排查流程图)
KEIL Map文件实战:如何从内存分布图揪出栈溢出元凶(附排查流程图) 在嵌入式开发中,内存问题往往是最隐蔽也最令人头疼的bug之一。当你的STM32程序突然崩溃,或者某些变量莫名其妙地被修改时,栈溢出很可能是罪…...
你知道吗?其实这些都是AI——智能制造系统
智能制造系统 背景介绍 智能制造是现代工业革命的重要标志之一,通过整合先进的技术手段,实现了生产过程的自动化、信息化和智能化。传统的制造业往往依赖于人工操作和经验决策,存在生产效率低、资源浪费大、质量控制难等问题。智能制造系统通过对生产过程的全方位监控和优化…...
NVIDIA TAO实战:手写字符检测与识别模型优化
1. 基于NVIDIA TAO的手写字符检测与识别模型实战 在工业质检、物流分拣、金融票据处理等领域,手写字符的自动识别一直是个棘手的问题。传统OCR技术面对手写体时准确率往往不尽如人意,而定制化深度学习模型又面临数据准备复杂、训练周期长等挑战。最近我在…...
公共维修基金透明程序,颠覆物业暗箱操作,维修收支上链,业主共同监督。
定位仍然是:技术演示 思路参考,不涉及真实金融交易,不构成法律或审计建议。一、实际应用场景描述在住宅小区、写字楼等物业场景中,公共维修基金的使用常涉及:- 电梯维修- 外墙修缮- 管道更换- 消防设施维护理想状态是…...
Flutter 凉了没?Flutter 2026 的未来行程和规划,一些有趣的变化
最近刚好有人问我,说现在 Flutter 官方好像没什么消息了?都没什么 Flutter 活动?我只想说,现在办活动的,不是 AI 主题的谁给经费? 刚好这两天看到了 Flutter 官方宣布的 2026 的一些全球行程,其…...
Pydantic V2迁移踩坑实录:从V1.10升级到V2,我总结了这5个关键变化和避坑指南
Pydantic V2迁移实战:5个核心变更与平滑升级策略 如果你正在维护一个使用Pydantic V1.x的项目,升级到V2版本可能会让你既期待又忐忑。作为一个刚从V1.10成功迁移到V2的开发者,我想分享一些关键变化和实战经验,帮助你避开那些我踩过…...
电磁铁的磁性可以无限增强吗
电磁铁的磁性无法无限增强,这主要源于材料的磁饱和特性。当磁场强度达到临界值后,即便继续增大电流或增加线圈匝数,磁性也难以持续提升。铁芯材料内部存在大量微小磁畴,在外加磁场作用下,这些磁畴会逐渐转向与磁场一致…...
视觉定位技术:从GUI自动化到智能交互的演进
1. 视觉定位技术的本质与演进十年前我第一次接触GUI自动化测试时,还需要手动计算每个按钮的像素坐标。如今视觉定位技术已经让机器能够像人类一样"看懂"界面元素。这项技术的核心在于建立屏幕像素坐标与界面逻辑元素之间的智能映射关系。早期的基于坐标的…...
