C语言printf()、sprintf()、vsprintf() 的区别与联系
来源:互联网 发布:办公室椅子知乎 编辑:程序博客网 时间:2024/05/19 22:44
文章转自:http://blog.csdn.net/raito__/article/details/48860119
C语言printf()、sprintf()、vsprintf()的区别与联系
printf() 在控制台应用程序中最为常用,使用也很简单。其参数为格式化字符串。
函数原型:printf(const char *format,[argument]);
例如:
输出:sprintf() 用于将输出存到字符缓冲中。
函数原型:sprintf(char *buffer, const char *format, [argument]);
例如:
vsprintf() 与sprintf() 功能类似。
需要引入相关头文件 #include <stdarg.h>
函数原型: vsprintf(char *buffer, char *format, va_list param);
例如:
因此可以用 vsprintf() 来实现 sprintf()。
其中 va_start、va_end、va_list 是什么东东一会儿再解释,先往下看。
既然sprintf() 与 vsprintf() 功能类似,为什么不统一下,而且 vsprintf() 用法如此麻烦呢?
假设你想封装一个子函数 Myprintf() ,其功能是将格式化字符串输出两遍,若用 sprintf() 实现:
(错误的)代码:
当你尝试这么调用该函数时:
输出:
我也不知道它会输出几,但一定不会是 a=1,b=2 。
这显然是错误的!
为什么呢?
当你这么调用 Myprintf() 时,其中的sprintf() 实际上是这样的:
sprintf(s,"a=%d,b=%d")
而不是:
sprintf(s,"a=%d,b=%d",a,b) !!
因为这么调用的话只能解析到第一个字符串而无法解析到后面的参数。
所以类似这种封装用 sprintf() 是无法实现的,使用 sprintf() 只能原始的为它输入所有的参数而不能以传参的方式给它。
若用 vsprintf()那么这个问题就可以迎刃而解。
函数如下:
输出:
成功了!哇哈哈哈哈!!想想也是有点小激动!!!
现在来解释一下这个 vsprintf():
首先你要知道函数执行时,函数的参数是倒序压入栈中的,vsprintf() 为了能够解析你传给它的多个参数,你必须告诉它参数从哪里开始。
vadefs.h 头文件中这么定义 :typedef char * va_list,于是我们定义了一个 va_list ap 来保存参数起始地址。
va_start(ap,fmt) 就找出这个函数在栈中排列的一堆参数的起始地址,然后直接浏览栈中参数,并用 vsprintf() 实现格式化字符串的读取,最后 vs_end(ap) 释放ap,就像释放指针一样。通俗地说就是因为 vsprintf() 比 sprintf() 更加接近底层(栈),因此能实现这个目的,也是因此能用 vsprintf() 来实现 sprintf()。
打的手好酸~0.0 希望大家发现错误帮我指正,不幸感激!最后给懒得敲代码的童鞋附上这段演示代码:
- C语言printf()、sprintf()、vsprintf() 的区别与联系
- C语言printf()、sprintf()、vsprintf() 的区别与联系
- C语言printf()、sprintf()、vsprintf() 的区别与联系
- printf,sprintf,vsprintf 区别
- printf,sprintf,vsprintf 区别
- printf,sprintf,vsprintf 区别
- printf,sprintf,vsprintf 区别
- echo、print、print_r、var_dump、printf、sprintf 和 vsprintf 的区别
- printf、sprintf、vsprintf的使用取舍
- printf、sprintf、vsprintf和wvsprintf的使用
- printf(),sprintf(),vsprintf() 详解
- C语言 sprintf()函数 与 printf()函数
- “printf”与“sprintf”的使用方法区别
- printf与sprintf的区别和用法
- printf、sprintf与fprintf 的区别
- C语言中printf(),sprintf(),scanf(),sscanf()的用法和区别
- C语言中printf(),sprintf(),scanf(),sscanf()的用法和区别
- 浅析C语言中printf(),sprintf(),scanf(),sscanf()的用法和区别
- binder原理
- 应用部署的六种策略
- JAVA实现约瑟夫环
- 【基础】 EFI基本概念之HOB
- 解决Failed to load class "org.slf4j.impl.StaticLoggerBinder"问题
- C语言printf()、sprintf()、vsprintf() 的区别与联系
- 解决input、textarea里使用disable属性文字变灰问题
- spring通过编程的方式获取bean
- 解决 IDEA 发布到 Tomcat 项目的 404 和 相对路径 问题
- C# Winform中 如何进行UrlEncode编码及解码
- 积分表
- git操作记录
- 南邮CTF逆向题第一道Hello,RE!解题思路
- Windows CMD 命令行笔记