sprintf与snprintf区别

2023-11-03

sprintf的原型如下

  int sprintf(char *str, const char &format, ...);

sprintf是字符串格式化命令,主要功能是把格式化的数据写入字符串str中,返回值为写入str的字节数,结束字符\0’不计入内。其中, str是指要写入的缓冲区,format控制要写入str中数据的格式,例如%s、%d、%x等。

 

snprintf的原型:

int snprintf(char *str, size_t size, const char *format, ...);

snprintf是字符串格式化命令,主要功能是把格式化的数据写入字符串str中,最多写size个字节,包括自动添加在字符串末尾处的结束字符\0;返回值为写入str的字节数,包括结束字符\0

sprintfsnprintf将通过下列小程序说明:

#include <stdio.h>

#include <string.h>

int main()

{

    char name1[6] = {'\0'};

    char name2[6] = {'\0'};

    int size1 = sprintf(name1, "%s", "Arthur");

    printf("name1:%s, size1:%d\n", name1, size1);

    int size2 = snprintf(name2, strlen("Arthur"), "%s", "Arthur");

    printf("name2:%s, size2:%d\n", name2, size2);

    return 0;

}

程序输出为:

name1:Arthur size1:6

name2:Arthu, size2:6

为什么name2输出为“Arthu”呢?因为最多写入6个字节,且包括结束字符\0,所以在将"Arthur"写入name2时,结束字符\0将替换字符r,故name2为“Arthu”。

该程序有没有问题呢?

有,该程序越界了,但编译运行时不会报错,很难发现。系统为变量name1分配的6个字节的空间,使用sprintfname1%s的格式写入数据时,在数组name1起始的位置写入“Arthur”后,将在和name1相邻的第一个字节中写入结束字符\0,而该字节不是分配给name1的,如果name1相邻的内存中有数据,它将被结束字符\0覆盖,造成异常,因此尽量使用更为安全的snprintf函数,而不是sprintf

对于snprintf使用时要注意把格式化的数据写入字符串str中,最多只能写size个字节,包括自动添加在字符串末尾处的结束字符\0。例如想要将数组a中的内容以%02x的格式写入到buf中,如下

#include <stdio.h>

int main()

{

    char a[20] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9,

                          0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13};

    char buf[20*2] = {0};

    for(int i = 0; i < 20; ++i) {

        snprintf(&buf[i*2], 2, "%02x", a[i]);

    }

    printf("buf:%s\n", buf);

    return 0;

}

我们期望为buf000102030405060708090a0b0c0d0e0f10111213,实际输出却是

buf0

为什么呢?因为snprintf将每个a[i]"%02x"格式写入buf[i]时,每个a[i]buf指向的空间里占两个字节,第二个字节将被结束字符\0替代,因此buf中的内容为0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\01\01\01\01\0

程序的正确写法如下:

#include <stdio.h>

int main()

{

char a[20] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9,

                      0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13};

char buf[20*2 + 1] = {0};

for(int i = 0; i < 20; ++i) {

    snprintf(&buf[i*2], 3, "%02x", a[i]);

}

printf("buf:%s\n", buf);

return 0;

}

 

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

sprintf与snprintf区别 的相关文章

  • rockchip rk3368(px5)车载开发之路6,系统开机bootanimation播放视频需求

    本系列记载作者来到一个新的车载后装市场小公司 负责从新开始维护一套代码的心路过程 系统使用瑞芯微的rk3368芯片 版本是PX5 Android 8 0 release 20180726 从无到有的每个patch修改以及思考 其中着重点是驱
  • PyTorch知识点总结100问

    PyTorch知识点总结 什么是PyTorch 它有什么特点和优势 PyTorch中的张量 Tensor 是什么 它与NumPy中的数组有何区别 请介绍一下PyTorch的执行流程 PyTorch中的autograd是什么 它有什么作用 请
  • Salesforce中国区解散,谁是替代的最佳选择?

    摘要 全球第一大CRM厂商退出 对中国市场有何影响 8月3日 Salesforce中国区解散的消息 在IT业界引发热议 虽然是全球第一大CRM厂商 但Salesforce在中国区业务不多 整个团队只有60 70人规模 主要业务是全球500强
  • 分布式系统消息通信技术:MOM与RPC

    一 中间件 什么是中间件 中间件 Middleware 是处于操作系统和应用程序之间的软件 也有人认为它应该属于操作系统中的一部分 人们在使用中间件时 往往是一组中间件集成在一起 构成一个平台 包括开发平台和运行平台 但在这组中间件中必须要
  • ifconfig命令无法识别,提示“Command 'ifconfig' is available in '/sbin/ifconfig'”

    有台虚拟机 用的时候发现ifconfig命令不好用了 提示如下 Command ifconfig is available in sbin ifconfig The command could not be located because
  • 需求:vue用流程图展示数据

    问题描述 如标题所示 粗略的写了一版 没有细化 UI 红框的地方本来想用canvas自己写 但是找资料的时候发现了一个插件LeaderLine 非常符合要求 然后发现了一篇文章vue横向树级组件 流程图 组件递归 套用了一下 然后按照自己的
  • 将json-bigint处理为数值分区数组的字段全部自动转为字符串

    json bigint虽然能帮我们处理好id 但 他的模式 显然不是直接可以用的 我们如果要到业务逻辑单独处理 那就太麻烦了 对系统也非常不友好 我们可以在vue项目中 src目录下创建一个utils 下面创建一个conversionLon
  • 线程共享&&独有

    线程共享 进程代码段 进程的公有数据 利用这些共享数据 线程很容易的实现相互之间的通讯 进程打开的文件描述符 信号的处理器 进程的当前目录和进程用户ID与进程组ID 线程独有 线程ID 桟 错误返回码 error 线程优先级
  • IDEA配置仓库提交简易说明

    1 码云注册并创建仓库 2 IDEA顶部菜单VCS 如果没有 删除代码文件夹里面的 git文件 3 Create git 4 选择需要提交的代码文件夹 5 IDEA顶部菜单Git 6 Commit 提交暂存 选择需要提交的代码文件 选择Co
  • SQLi LABS Less-18

    第十八关请求方式为 GET请求 注入点为 User Agent 注入方式为 错误注入 第一步 判断注入方式 先看源码 后台代码对 特殊字符进行了过滤 常规的注入方式行不通 只有通过代码审计来判断注入方式 登录成功后 有一个保存用户主机信息的
  • 文本三剑客之sed

    sed简介 sed 是Linux中提供的一个外部命令 他是一个行 流 编辑器 非交互式的对文件内容进项增删改查操作 那它和文本编辑器有什么区别呢 区别是 文本编辑器 编辑对象是文件 行编辑器 编辑对象是文件中的行 也就是前者一次处理一个文本
  • Anaconda使用conda连接网络时,出现网络错误CondaHTTPError(包括Anaconda安装与入门)

    今天准备安一个Anaconda来管理我的Python环境 在官网下载支持Python3 7的版本 直接安装即可 使用Anaconda Navigator可以方便地创建环境和管理各种外部包 conda version 查看版本 是否安装成功
  • element-ui 中标签el-select选中无反应问题

    el select标签 如果外部还嵌套循环 点击选中标签无反应 删除也不好使 原因由于层次太多 导致render函数没有自动更新 在el select标签内加入 change forceUpdate 强制刷新视图即可
  • 怎样删除Github中的项目

    我们在GitHub上创建项目的时候 如果想要删除当前项目 怎样进行操作呢 下面就简单介绍一下怎样去删除GitHub中的项目 1 选择要删除的项目 2 进入项目中的setting 设置 中 3 一直下拉 看到有红色字体出现 进入Danger
  • 都2022年了,出去面试连分布式锁的源码你都不会画?

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 目录 一 写在前面 二 Redisson实现Redis分布式锁的底层原理 1 加锁机制 2 锁互斥机制 3 watch dog自动延期机制 4 可重入加锁机制 5 锁
  • Linux基础笔记17

    磁盘基础概念知识 计算机主要存储媒介之一 由一个或多个铝制 玻璃的碟片组成 碟片外覆盖具有铁磁性材料 磁盘内部由磁道 柱面 扇区 磁头等关键部位组成 Linux 系统中硬件设备文件放在 dev 下 不同磁盘接口 系统识别的设备名称不一样 I
  • MySQL查询操作

    MySQL查询操作 1 建表 CREATE TABLE 学生 学号 char 7 NOT NULL PRIMARY KEY 姓名 char 8 NOT NULL 性别 char 2 年龄 tinyint 入学时间 datetime 专业 v

随机推荐

  • 【科普贴】MOS管开关原理及应用详解

    前言 MOS管通常被用作电源开关使用 通常使用PMOS做为上管 将NMOS做为下管使用 当然也有反过来使用的场景 但使用较少 此贴为科普贴 就不做累述了 MOS原理介绍 1 NMOS管介绍 电流方向从D S 漏极流向源极 导通条件为VGS有
  • i.mx287学习笔记4-使用QT控制LED

    上面是我的微信和QQ群 欢迎新朋友的加入 目录 1 安装QT CREATOR 2 硬件连接 3 驱动源码 4 编译驱动 测试驱动 5 创建QT界面 6 编译QT 7 运行 8 源码 1 安装QT CREATOR sudo apt get i
  • AVPlayer 播放的时候有黑色边

    iOS视频开发中 使用系统的AVPlayer的几率非常高 然 在部分Plus机型会出现黑边的情况 平时不容易发现 但你的视频若是白色色调 就比较明显 解决方法 修改AVPlayerLayer的属性 使playerLayer光栅化 即位图化
  • python需要学多长时间

    随着人工智能和机器学习的持续升温 Python 目前是首选的AI语言 在数据科学和AI中占据主导地位 而且随着互联网的发展 Python的应用越来越广泛 学习Python的人也越来越多 主要是因为Python门槛低 上手很快 而且通用性和实
  • npm ERR! 400/403 Bad Request - PUT https://registry.npmjs.org/xxx- “xxx“ is invalid for new packages

    npm ERR 403 403 Forbidden PUT https registry npmjs org df ui You do not have permission to publish df ui Are you logged
  • TypeError: 'builtin_function_or_method' object is not subscriptable的一种错误情况

    TypeError builtin function or method object is not subscriptable的一种错误情况 初学python 今天在做练习时为一个Error苦恼了很久 最终找到了解决方法 错误代码块如下
  • Contrastive Self-Supervised Learning 的对比学习框架和设计新方法

    翻译自 建议阅读原文 https towardsdatascience com a framework for contrastive self supervised learning and designing a new approac
  • OpenGL点精灵(Point Sprite)

    From http iiunknown blogbus com logs 48250551 html 在很多粒子的demo中 看到把粒子显示成一个个小球 如果你以为那是用glutSolidShpere画出来的话 你就错了 上万个粒子 每个球
  • 织梦网站服务器配置未见,DedeCms系统配置参数无法显示的解决方法

    Dedecms后台系统基本参数不显示的原因 这个是我使用dedecms建站来遇到的问题 到dedecms官方看了下 什么玩意的信息都没有 蛋疼的官方 对于我们这等草根来说dedecms官方基本没有指导作用 都是论坛的会员在哪儿里互相帮助 此
  • 患病率对 Delta 和样本量的影响 - 使用 R 语言进行计算

    患病率对 Delta 和样本量的影响 使用 R 语言进行计算 概述 在研究和实验设计中 样本量是一个重要的考虑因素 样本量的确定需要考虑多个因素 其中之一是患病率 即事件发生的概率 患病率的不同取值会对所需的样本量和效果大小 Delta 产
  • Flutter学习六:GestureDetector练习

    在Android中所有View都可以设置OnClick事件 但是在Flutter中除开少数自带Press事件的widget 大部分控件都是不带事件的 如果需要添加事件 就可以用GestureDetector作为父widget包裹需要添加事件
  • 华为OD真题练习

    华为OD真题练习 华为OD机考真题练习 题目描述 任务混部 公司创新实验室正在研究如何最小化资源成本 最大化资源利用率 请你设计算法帮他们解决一个任务混部问题 有taskNum项任务 每个任务有开始时间 startTime 结束时间 end
  • 获取ItemsControl中当前item的binding数据

    直接用 Binding 就可以了 如下
  • 负载均衡策略之AbstractLoadBalancerRule和RandomRule源码解读

    一 负载均衡类图 二 AbstractLoadBalancerRule解读 负载均衡策略的抽象类 public abstract class AbstractLoadBalancerRule implements IRule IClient
  • 微信小程序实现 3秒后自动跳转到指定页面

    需求描述 在某个页面 当用户点击 按钮 时 如果用户没有登录 则 3 秒后自动跳转到登录页面 思路 1 判断用户有没有进行登录 如果没有登录 那么就调用this delayTime 这个方法 2 首先写一个展示弹框的方法 this show
  • typescript interface定义数组每一项都为对象

    定义一个方法 返回一个数组 数组的每一项均为对象 对象中包含label和value两个属性 创建一个public ts文件 javascript实现 javascript 实现 export const formatYear functio
  • 基于深度卷积神经网络的小样本分割算法综述

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 本文转自 视学算法 介绍 深度卷积神经网络在图像分类 目标检测 语义分割等许多视觉理解任务上都取得了重大突破 一个关键的原因是大规模数据集的可用性 比如 ImageNet
  • Git使用个人访问令牌提交代码到仓库

    2021年8月13日开始 GitHub在使用Git操作远程仓库时不再支持使用用户名密码形式进行身份验证 需使用个人访问令牌 使用Git操作GitHub仓库时使用用户名密码进行身份验证会报错 一 创建个人访问令牌 1 1 在GitHub官网右
  • 复习:详解函数重载

    什么是函数重载 一组函数 处于同一个作用域 其中函数名相同 参数列表的个数或类型不同 那么这一组函数就成为函数重载 一组函数要称得上函数重载 一定是处在同一个作用域中函数名同 参数列表同 返回值不同 不叫重载 因为函数符号都相同函数重载是通
  • sprintf与snprintf区别

    sprintf的原型如下 int sprintf char str const char format sprintf是字符串格式化命令 主要功能是把格式化的数据写入字符串str中 返回值为写入str的字节数 结束字符 0 不计入内 其中