c语言printf、sprintf、vsprintf用法和区别

2023-11-19

 

printf、sprintf、vsprintf 通常用于格式化字符串,通俗来说就是字符串打印或显示格式转换。

printf、sprintf 需要包含 <stdio.h> 头文件,vsprintf 需要包含 <stdarg.h>。

使用下面例程,介绍他们的用法、区别和关系。

 

我的VS2019在运行c程序时候出现点小问题,提示函数非安全。需要使用 sprintf_s、vsprintf_s。

替换后,实验结果有一些不对劲。换了下平台,在树莓派上编译运行,结果正常。以下实验现象均为树莓派运行输出。

 

 

        使用 printf、sprintf、vsprintf 分别输出 a、b 的值。

  • printf

#include <stdio.h>

int main(int argc, char* argv)
{
	int a = 10,b = 20;
	
	printf("a=%d,b=%d\r\n", a, b);
	return 0;
}
------------------------------------------------------------------
a=10,b=20

 

实际运行现象:

 

        printf最为简单,只需要添加字符串,和%格式说明,即可输出用户内容。

 

 

  • sprintf

#include <stdio.h>

int main(int argc, char* argv)
{
	char str[20];
	int a = 20,b = 20;
	
	sprintf(str, "a=%d,b=%d\r\n", a, b);
	printf(str);
	return 0;
}
-------------------------------------------------------------------
a=20,b=20

 

实际运行现象:

 

        sprintf :发送格式化输出到指定数组。格式化用法与 printf一致,相当于把 printf输出的内容放入指定数组中

 

 

  • vsprintf

#include <stdio.h>
#include <stdarg.h>

void myPrintf(char* fmt, ...)
{
	char str[20];
	
	va_list ap;
	va_start(ap, fmt);
	vsprintf(str, fmt, ap);
	va_end(ap);
	
	printf(str);
}

int main(int argc, char* argv)
{
	int a = 30,b = 20;
	
	myPrintf("a=%d,b=%d\r\n", a, b);
	return 0;
}
-------------------------------------------------------------------
a=30,b=20

 

实际运行现象:

 

        vsprintf使用不确定参数的方式封装,可直接输入数组和未知的参数。从而精简 sprintf需要先创建数组再传入参数的操作。

        vsprintf 与 sprintf 功能相似,都是将格式化内容输出到指定数组。不同的是使用方法和用途有些不一样。

        看过上面的例程,有没有感觉 sprintf 也能替换 vsprintf,实现相同的功能,何必搞出 va_list、va_end 一堆的麻烦事???

        那么就来试着替换一下。(实际这种用法是错误的)

#include <stdio.h>

void myPrintf(char* fmt, ...)
{
	char str[20];
	
	sprintf(str, fmt);
	printf(str);
}

int main(int argc, char* argv)
{
	int a = 30,b = 20;
	
	myPrintf("a=%d,b=%d\r\n", a, b);
	return 0;
}
-------------------------------------------------------------------
a=20,b=2125550836

 

实际运行现象:

 

        欸!!!有趣的来了,这tm输出的完全不对啊,我输入的明明是30和20,输出的是20和2125550836。

 

所以 sprintf 不适用于这种封装的传参,sprintf不能以不确定传参的方式来格式参数。

而 va_start(ap,fmt) 从实现方式来讲,它使va_list类型变量ap指向被传递给函数的可变参数表中的第一个参数,然后在栈中浏览参数,最后由于va_end(ap)释放掉ap。

 

最后总结:对于传参中参数类型和个数不确定的格式转换,请使用 vsprintf。

 

 

 

 

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

c语言printf、sprintf、vsprintf用法和区别 的相关文章

  • 如何向 UWP 项目添加 .NET dll 引用?

    我有几个适用于 NETv4 x 的 NET dll 项目 我将版本更改为 4 6 1 并重新构建 没有出现问题 当我尝试从 UWP 项目向它们添加引用时 出现错误 项目的目标是 NETCore 而文件引用的目标是 NET框架 这不是受支持的
  • 如何从当前 .NET 表单/应用程序发送密钥 F12

    我非常确定以下按钮激活的表单代码应该在我的 C 应用程序中引发 Control F12 SendKeys F12 但它似乎并没有继续进入 Windows shell 并激活另一个正在侦听它的程序 我的键盘可以用 看起来发送键在某处被拦截 并
  • LINQ to XML - 如何正确使用 XDocument

    现在我首先要说的是 这确实是一项任务 然而 在我遇到 Linq to XML 语法之前 我几乎已经完成了它 我有 2 个课程 曲目和 CD 现在作为作业的一部分 我创建了一张 CD 然后向其中添加了一些曲目 在搜索了大量完美解释了如何从 x
  • .NET 可移植类库中的 .ToShortDateString 发生了什么

    我想知道为什么没有 ToShortDateString在 NET 可移植类库中 我有 2 个项目 Silverlight 和常规 NET 类库 使用相同的代码 并且代码涉及调用 ToShortDateString on a DateTime
  • 有没有比这更快的方法来查找目录和所有子目录中的所有文件?

    我正在编写一个程序 需要在目录及其所有子目录中搜索具有特定扩展名的文件 这将在本地驱动器和网络驱动器上使用 因此性能是一个问题 这是我现在使用的递归方法 private void GetFileList string fileSearchP
  • 如何避免选择项目时 winforms 树视图图标发生变化

    我正在一个小型 C Winforms 应用程序中尝试树视图 我已经以编程方式将 ImageList 分配给树视图 并且所有节点都很好地显示了它们的图标 but当我单击一个节点时 它的图标会发生变化 变为 ImageList 中的第一个图像
  • glDrawElements 只绘制半个四边形

    这是我的功能 void Object draw2 if mIsInitialised return Tell OpenGL about our vertex and normal data glEnableClientState GL VE
  • 如何检测斑点并将其裁剪成 png 文件?

    我一直在开发一个网络应用程序 我陷入了一个有问题的问题 我会尝试解释我想要做什么 在这里您看到第一个大图像 其中有绿色形状 我想要做的是将这些形状裁剪成不同的 png 文件 并使它们的背景透明 就像大图像下面的示例裁剪图像一样 第一张图像将
  • CMake - 将预构建库链接到 C# 项目

    我正在使用 CMake 构建 C 库 该库依赖于已构建的库 dll 我似乎无法让图书馆链接到我的图书馆 我尝试过使用target link libraries mylib external lib 我也尝试过暴力破解 reference e
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • 为什么 C 函数不能返回数组类型?

    我是 C 语言新手 想知道 为什么 C 函数不能返回数组类型 我知道数组名是数组第一个值的地址 而数组是 C 中的二等公民 您自己已经回答了这个问题 数组是二等公民 C 按值返回 数组不能按值传递 因此不能返回它们 至于为什么数组不能按值传
  • 编写专门用于类及其子类的函数模板

    我正在尝试编写一个函数模板 一个版本应该用于不满足另一版本标准的所有类型 当参数是给定类的基类或该类本身时 应使用另一个版本 我尝试过超载Base 但是当类派生自Base 他们使用通用的 而不是特定的 我也尝试过这种 SFINAE 方法 s
  • 通过 MSBuild 调用 cl.exe 时无限期挂起

    我正在尝试在我的 主要是 C 项目上运行 MSBuild 想象一下一个非常庞大的代码库 Visual Studio 2015 是有问题的工具集 Windows 7 SP1 和 VS 2015 更新 2 即使使用 m 1 从而迫使它仅使用一个
  • 为什么我不能在扩展 List 的类中调用 OrderBy?

    我有一堂课 Deck 其中包含一个名为的方法Shuffle 我正在致力于重构Deck延长List
  • C# - 为什么我需要初始化 [Out] 参数

    我有几个从本机 dll 导入的方法 使用以下语法 internal static class DllClass DllImport Example dll EntryPoint ExampleFunction public static e
  • 宏观评价[重复]

    这个问题在这里已经有答案了 可能的重复 未定义的行为和序列点 https stackoverflow com questions 4176328 undefined behavior and sequence points 我无法理解以下宏
  • 如何仅更改 DateTime 的日期部分,同时保留时间部分?

    我在代码中使用了很多 DateTime 我想将这些日期时间更改为我的特定日期并保留 时间 1 2012 02 02 06 00 00 gt 2015 12 12 06 00 00 2 2013 02 02 12 00 00 gt 2015
  • 当我读取 500MB FileStream 时出现 OutOfMemoryException

    我使用 Filestream 读取大文件 gt 500 MB 但出现 OutOfMemoryException 任何有关它的解决方案 我的代码是 using var fs3 new FileStream filePath2 FileMode
  • 在 C# 中读取/写入命令行程序

    我正在尝试与 C 的命令行程序进行对话 它是一个情绪分析器 它的工作原理如下 CMD gt java jar analyser jar gt Starting analyser 这是我想从我的 C 程序插入内容的地方 例如 I love y
  • 最后从同一类中的其他构造函数调用构造函数

    我在这里读到可以调用另一个构造函数从同一类中的另一个构造函数调用构造函数 https stackoverflow com questions 829870 calling constructor from other constructor

随机推荐

  • Matlab 安装和使用xgboost的详细步骤(源码+安装包)

    几个重要的ref 看完后你可以解决你的问题 知乎官网指导 官网讨论 安装MinGW w64 安装需要的模块和源码可以从下面地址下载 链接 https pan baidu com s 1oqCMI7VmVxDzf9Vbaf4VJw pwd 1
  • Arduino与HX711称重传感器握手

    Arduino教程传送门 Arduino与HX711称重传感器握手 1 0 简介 2 0 实验材料 3 0 实验步骤 3 1 根据原理图搭建电路 3 2 新建sketch 拷贝如下代码并进行保存编译上传 3 3 实验现象 4 0 总结 1
  • python基础(更新中)

    文章目录 print函数 数据类型 基本类型 数据拼接 数据转换 条件判断 标识符 关键字 注释 使用帮助 运算符 转义字符 三重引号字符串 字符串格式化 符号格式化字符串 字符串格式的书写 常用格式字符的含义 format 方法格式化字符
  • python loop详解_Python进阶学习笔记(3)-Loop

    while 语法结构 用 隔开 while condition expression x 1 while x lt 4 print x x x 1 Initialize offset offset 8 Code the while loop
  • 硬件基础之电容篇

    一 技术理论 1 电容定义 两个相互靠近的金属板中间夹一层绝缘介质组成的器件 当两端存在电势差时 由于介质阻碍了电荷移动而积累在金属板上 衡量金属板上储存电荷的能力 称为电容 相应的器件称为电容器 电容的符号为C 单位为法拉 F 电容越大
  • 宝塔面板设置域名后无法访问

    设置域名前 需要先备案通过 并解析到宝塔面板的服务器上面才能访问 然后没有做上面相关的时候 设置了域名导致不能访问 解决方式如下 删除域名配置 删除该配置即可 rm f www server panel data domain conf 然
  • HADOOP集群搭建

    1首先新建文件夹路径 root hdp01 home mkdir p home hadoop apps 2修改主机名 vi etc sysconfig network 3配置内网域名映射 vi etc hosts 4配置ssh免密登陆 1在
  • 伴随矩阵及其运算

    关键公式 A B A B
  • mysql jdbc url连接超时_JDBC链接出现超时问题

    今日线上突发一个问题 应用假死 不接受http请求 排查日志 发现有大量的 The last packet successfully received from 异常 首先排查数据库和链接池配置 destroy method close g
  • 利用OpenCV实现软件自动识别核酸检测时间

    文章目录 问题介绍 一 前期准备工作 1 Python的安装 2 安装OpenCV Python开发包 3 安装Tesseract OCR 二 编写程序 1 引入库 2 使用Tesseract做文字识别 OCR 3 筛选日期 4 日期运算
  • 【架构设计】阿里开源架构Cola4.0的项目实践:订单系统

    项目介绍 使用SpringBoot MybaitsPlus Cola 整洁面向对象分层架构 4 0重构订单功能 项目地址 Gitee https gitee com charles ruan smile cola Github https
  • kvm详解【10】:迁移

    文章目录 一 静态迁移 二 动态迁移 一 静态迁移 静态迁移就是虚拟机在关机状态下 拷贝磁盘文件与配置文件到目标虚拟主机中 实现的迁移 分为以下情况 虚拟主机各自使用本地存储存放虚拟机磁盘文件 本文实现基于本地磁盘存储虚拟机磁盘文件的迁移方
  • 值得一看的WinPhone入门系列文章

    今天发现了一些Windows Phone开发入门的系列文章 很适合初学者 下面把其连接总结如下 1 概论 http www winphonecoder com forum php mod viewthread tid 185 extra p
  • buuctf web [ACTF2020 新生赛]Upload

    明了但不明显的文件上传 传个试试 行 抓包吧 php格式不行 就先上传要求的格式 jpg png gif 抓到上传的包之后 再修改成我们想要的 常见的php格式绕过有 php php3 php4 php5 phtml pht 挨个试试 这是
  • Duplicate entry '0' for key 'PRIMARY'的一种可能的解决办法

    在MySQL设计好数据库往往数据库中插入数据的时候 因为主键ID默认是不赋值的 只给其他项目赋值了 相关的SQL代码是这样的 StringBuilder strSql new StringBuilder strSql Append inse
  • 【深度学习】Pytorch 系列教程(十三):PyTorch数据结构:5、数据加载器(DataLoader)

    目录 一 前言 二 实验环境 三 PyTorch数据结构 0 分类 1 张量 Tensor 2 张量操作 Tensor Operations 3 变量 Variable 4 数据集 Dataset 5 数据加载器 DataLoader 一
  • C++ using

    一 C 11前的使用 1 using申明 c primer plus 中 using申明 using 限定名称 限定名称 包含名称空间的名称 举例 using std cout 2 using编译指令 举例 using namespace
  • 华为od机考真题-HJ17坐标移动(中等)

    data input l r 0 0 for ad in data split ad
  • Generative AI 新世界:大型语言模型(LLMs)概述

    在上一篇 Generative AI 新世界 文本生成领域论文解读 中 我带领大家一起梳理了文本生成领域 Text Generation 的主要几篇论文 InstructGPT RLHF PPO GPT 3 以及 GPT 4 本期文章我将帮
  • c语言printf、sprintf、vsprintf用法和区别

    printf sprintf vsprintf 通常用于格式化字符串 通俗来说就是字符串打印或显示格式转换 printf sprintf 需要包含