printf,sprintf,sprintf_s,_snprintf_s,vsprintf,vsnprintf,_vsnprintf_s,_vscprintf等格式化字符串使用与区别

2023-11-12

最近在为新做的项目找个好用的第三方日志库,感觉log4cpp挺好用的,日志输出使用了格式化字符串,不同的函数功能不同,而且变异版本比较多,自己都有点搞昏了,网上搜索也比较笼统,下面是自己coding测试格式化字符串的过程(vs2015,win10  x64环境),供参考

有C语言写作历史的程序员往往特别喜欢printf 函数。即使可以使用更简单的命令(例如puts),但printf 出现在Kernighan和Ritchie的「hello, world」程序中一点也不会令人惊奇。我们知道,增强后的「hello, world」最终还是需要printf 的格式化输出,因此我们最好从头开始就使用它。

printf 函数说明如下:

int printf (const char * szFormat, ...);
第一个参数是一个格式化字符串,后面是与格式化字符串中的代码相对应的不同类型多个参数。

这个函数比较简单,如下,没什么好说的

  

sprintf 函数定义如下:

int sprintf (char * szBuffer, const char * szFormat, ...);
第一个参数是字符串缓冲区,后面是一个格式字串。sprintf不是将格式化结果标准输出,而是将其存入szBuffer。该函数返回该字符串的长度。

sprintf函数vs2015提示该函数可能不安全,建议使用sprintf_s函数

我们使用sprintf_s如下:

几乎每个人都经历过,当格式化字符串与被格式化的变数不合时,可能使printf 执行错误并可能造成程序当掉。使用sprintf 时,您不但要担心这些,而且还有一个新的负担:您定义的字符串缓冲区必须足够大以存放结果。Microsoft 专用函数_snprintf 解决了这一问题,此函数引进了另一个参数,表示以字节计算的缓冲区大小。

同样_snprintf函数vs2015也提示该函数可能不安全,建议使用_snprintf_s函数

可以看到输出字符串被截断了。

重点来了

vsprintf 函数定义如下:

int vsprintf(char *string, char *format, va_list param);

vsprintf 是sprintf 的一个变形,它只有三个参数。vsprintf 用于执行有不定数量参数的函数,类似printf 格式。vsprintf的前两个参数与sprintf相同:一个用于保存结果的字符串缓冲区和一个格式化字符串。第三个参数是指向格式化参数队列的指针。实际上,该指针指向在堆栈中供函数调用的变量。va_list、va_start和va_end宏(在STDARG.H中定义)帮助我们处理堆栈指针。va_start宏将pArg设置为指向一个堆栈变量,该变量位址在堆栈参数szFormat的上面。

同样vsprintf 函数vs2015也提示该函数可能不安全,我们使用vsprintf_s函数

在寻找第三方日志库的过程中,格式化字符串需要计算当前格式化字符串的长度,如果长度不够可能越界发生崩溃,接下来这个函数能帮我们获取格式化字符串长度;

_vscprintf函数定义如下:

int _vscprintf(const char *format,va_list argptr);
Returns the number of characters in the string referenced by a list of arguments
大概意思就是说:返回格式化列表字符字节数

这样就可以按照格式化字符串的大小动态申请缓冲区的大小,方便又实用,不会因为固定缓冲区大小导致崩溃的 问题发生

这个函数解决了本次格式化字符串的问题~~

还有两个函数

vsnprintf,_vsnprintf_s,参考如下验证:

由于许多Windows早期程序使用了sprintf 和vsprintf,最终导致Microsoft 向Windows API中增添了两个相似的函数。

当然,随著宽字符的发表,sprintf 类型的函数增加了许多,使得函数名称变得极为混乱。类似的函数还有很多变种,有兴趣的朋友自行度娘

https://download.csdn.net/download/xianzongtanxun/10605842​​​​​​​ 放上例子代码供参考

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

printf,sprintf,sprintf_s,_snprintf_s,vsprintf,vsnprintf,_vsnprintf_s,_vscprintf等格式化字符串使用与区别 的相关文章

随机推荐

  • Pycharm配置本地解释器

    由于Pycharm自带解释器 所以默认情况下我们是无法使用本地安装好的第三方库的 这个时候我们需要在Pycharm中配置本地的解释器 1 setting 2 add 3 找到本地的python解释器的路径
  • 超级详细找CALL写CALL教程[转]

    首先我们要知道一点 为什么要找CALL CALL是什么 大家知道易里的子程序吧如何调用子程序的 这里的CALL就是调用子程序的意思 那问了为什么要找他的 答案是 当你些个游戏的外挂用模拟键盘操作的时候 被操作的永远是当前窗口 当窗口切换的时
  • 多元时间序列因果关系分析研究综述

    Granger因果分析基本方法 目录 Granger因果分析基本方法 条件 Granger 因果模型 多元混沌时间序列因果分析 高维时间序列的因果分析 Lasso Granger因果模型 非线性Granger因果模型 Granger因果关系
  • DHCP 理论

    DHCP的基本工作过程 有4个阶段 discover offer request ack nak 抓包 标准地址池 1 地址段 网络号 掩码 2 网关 用于不同网段通信 3 dns DHCP的offer包部分字段 option 1 掩码 o
  • 讯飞星火认知大模型可以内测了

    以ChatGPT为代表的AI产品层出不穷 每天在社交媒体都可以看到AI领域的新成果 写文章 写代码 绘画 各种功能让人大呼神奇 4月24日 讯飞星火认知大模型来了 只需一个指令 懂你所言 答你所问 创你所需 解你所难 学你所教 一旦掌握正确
  • scp传输文件的命令

    scp传输文件的命令 scp传输文件的命令 一 scp常规的使用方式 scp可以进行简单的远程复制文件的功能 它是一个在各个主机之间进行复制或文件传输的一个命令工具 它使用一种同ssh一样的安全机制来进行文件的传输 注意 下面定义的远程计算
  • 云计算day08-Kubernetes_K8s

    文章目录 1 k8s的架构 2 k8s集群的安装 2 1 环境准备 2 2 k8s master上配置 2 3 master节点安装kubernetes 2 4 node节点安装kubernetes 2 5 所有节点配置flannel网络
  • 简单阐述下决策树、回归、SVM、神经网络等算法各自的优缺点?

    正则化算法 Regularization Algorithms 集成算法 Ensemble Algorithms 决策树算法 Decision Tree Algorithm 回归 Regression 人工神经网络 Artificial N
  • 检测浏览器是否开启firebug以及如何避免调试信息带来的脚本错误

    今天发现使用Gmail的时候开启firebug 会给出提示 在已知情况下 除非正确配置 Firebug 否则它会使 Gmail 运行缓慢 解决此问题 隐藏 感叹Gmail真是事无巨细 面面都考虑到了 于是想了解Gmail是如何检测用户是否开
  • vue解决Not allowed to load local resource

    前言 在进行通过本地路径进行加载图片的时候 突然就报了这个问题 Not allowed to load local resource 这个是由于安全性的问题 导致浏览器禁止直接访问本地文件 那么 这边我说一下我具体是怎么解决的吧 问题描述
  • linux alien命令将deb安装包和rpm安装包进行相互转换

    alien命令作用 alien是一个用于在各种不同的Linux包格式相互转换的工具 其最常见的用法是将 rpm转换成 deb 或者反过来 alien命令安装 Debian系linux可使用下面命令安装alien sudo apt get i
  • 分享一下我做软件测试这些年的心路历程,以及软件测试的发展方向。

    为什么入软件这行 很多人问我 一个女孩子做这个不太好 做不长久 特别年龄大了更不好做 我只是很随意的说专业对口 我能说是看上这个行业的高工资和技术范么 这样太俗了 然而就是这个俗气的理由让我走上这一条路 且想一直走下去 为什么呢 一是因为做
  • Circuit Board

    http acm zju edu cn onlinejudge showProblem do problemCode 164 On the circuit board there are lots of circuit paths We k
  • NDK使用遇到的那些事(持续更新当中)

    AppCamera transformNativeLibsWithStripDebugSymbolForDebug FAILURE Build failed with an exception What went wrong Executi
  • 性能、自动化面试题

    1 性能测试流程是怎么样的 2 如果测试过程中发现响应时间比较长 怎么分析 1 排查负载机 是不是负载机资源不足引起的 看看脚本是不是有问题 2 查看所消耗的时间主要是在网络传输上还是服务器上 网络传输 结合网络吞吐量图计算宽带是不是有瓶颈
  • 非spring注入使用RedisTemplate,需先调用afterPropertiesSet()方法

    错误信息 Exception in thread main java lang IllegalArgumentException template not initialized call afterPropertiesSet before
  • Piggy-Bank【暑期集训F题】【完全背包】

    Before ACM can do anything a budget must be prepared and the necessary financial support obtained The main income for th
  • 一文教你理解傅里叶变换及MATLAB在求傅里叶变换中的应用

    大纲 从积分变换谈起 积分变换的基本概念 积分变换的来源 傅里叶级数 傅里叶级数的相关基础概念 傅里叶级数的基石 三角函数系及其正交性 三角函数系 三角函数系的正交性 傅里叶级数的含义 傅里叶系数的导出 傅里叶级数收敛条件与收敛定理 从周期
  • PCIe架构下memory空间、IO空间、PCIe配置空间简介

    转载自 PCIe架构下memory空间 IO空间 PCIe配置空间简介 1 4种空间迷魂阵 PCIe架构下定义了4种地址空间 Memory空间 IO空间 配置空间和message空间 我们先看一下PCIe spec关于这四种空间的定义 1
  • printf,sprintf,sprintf_s,_snprintf_s,vsprintf,vsnprintf,_vsnprintf_s,_vscprintf等格式化字符串使用与区别

    最近在为新做的项目找个好用的第三方日志库 感觉log4cpp挺好用的 日志输出使用了格式化字符串 不同的函数功能不同 而且变异版本比较多 自己都有点搞昏了 网上搜索也比较笼统 下面是自己coding测试格式化字符串的过程 vs2015 wi