printf,sprintf,vsprintf 区别【转】

简介:

转自:http://blog.csdn.net/anye3000/article/details/6593551

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

但有个坏消息:在Windows程序中不能使用printf。虽然Windows程序中可以使用大多数C的执行时期函数库。实际上,许多程式写作者更愿意使用C的内存管理和I/O函数而不是Windows中等效的函数-Windows对标准输入和标准输出没有概念。在Windows程序中可使用fprintf,而不是printf。

还有一个好消息,那就是仍然可以使用sprintf 及sprintf 系列中的其他函数来显示文字。这些函数除了将内容格式化输出到第一个参数所提供的字符串缓冲区以外,其功能与printf 相同。然后便可对该字符串进行操作(例如将其传给MessageBox)。

 

如果您从未使用过sprintf (我第一次开始写Windows程序时也没用过此函数),这里有一个简短的执行实体。

printf 函数说明如下:

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

 

sprintf 函数定义如下:

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

在命令行程序中,

printf ("The sum of %i and %i is %i", 5, 3, 5+3) ;
的功能相同于

char szBuffer [100] ;
sprintf (szBuffer, "The sum of %i and %i is %i", 5, 3, 5+3) ;
puts (szBuffer) ;
在Windows中,使用MessageBox显示结果优于puts。

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

 

vsprintf 函数定义如下:

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

vsprintf 是sprintf 的一个变形,它只有三个参数。vsprintf 用于执行有不定数量参数的函数,类似printf 格式。vsprintf的前两个参数与sprintf相同:一个用于保存结果的字符串缓冲区和一个格式化字符串。第三个参数是指向格式化参数队列的指针。实际上,该指针指向在堆栈中供函数调用的变量。va_list、va_start和va_end宏(在STDARG.H中定义)帮助我们处理堆栈指针。本章最后的SCRNSIZE程式展示了使用这些宏的方法。使用vsprintf 函数,sprintf 函数可以这样编写:

int sprintf (char * szBuffer, const char * szFormat, ...)
{
int     iReturn ;
va_list pArgs ;
va_start (pArgs, szFormat) ;
iReturn = vsprintf (szBuffer, szFormat, pArgs) ;
va_end (pArgs) ;
return iReturn ;
}
va_start宏将pArg设置为指向一个堆栈变量,该变量位址在堆栈参数szFormat的上面。

由於许多Windows早期程序使用了sprintf 和vsprintf,最终导致Microsoft 向Windows API中增添了两个相似的函数。Windows的wsprintf 和wvsprintf 函数在功能上与sprintf 和vsprintf 相同,但它们不能处理浮点格式。

当然,随著宽字符的发表,sprintf 类型的函数增加了许多,使得函数名称变得极为混乱。下面列出了Microsoft 的C执行时期函数库和Windows支持的所有sprintf 函数。

 

ASCII 宽字符 常规 
参数的变量个数       
标准版 sprintf swprintf _stprintf 
最大长度版 _snprintf _snwprintf _sntprintf 
Windows版 wsprintfA wsprintfW wsprintf 


参数队列的指针        
标准版 vsprintf vswprintf _vstprintf 
最大长度版 _vsnprintf _vsnwprintf _vsntprintf 
Windows版 wvsprintfA wvsprintfW wvsprintf

在宽字符版的sprintf 函数中,将字符串缓冲区定义为宽字符串。在宽字符版的所有这些函数中,格式化字符串必须是宽字符串。不过,您必须确保传递给这些函数的其他字符串也必须由宽字符组成。











本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/5842378.html,如需转载请自行联系原作者


相关文章
|
安全 前端开发 Java
Springboot中如何优雅的进行字段以及业务校验
Springboot中如何优雅的进行字段以及业务校验
420 0
文件覆盖写入和追加写入:使用场景、命令和技巧详解
文件覆盖写入和追加写入:使用场景、命令和技巧详解
1998 0
|
5月前
|
人工智能 自然语言处理 搜索推荐
AI赋能教育与阿里云通义千问的结合
本简介介绍了AI技术如何赋能教育行业,结合阿里云“通义千问”大模型,助力海豚大数据及人工智能实验平台实现个性化教学、智能答疑与资源优化,推动高校与企业人才培养模式革新,构建终身学习生态体系。
424 1
|
算法 数据挖掘 调度
【调度算法】NSGA III(1)
【调度算法】NSGA III
1984 0
|
存储 文件存储 数据库
在飞牛 NAS 上部署宝塔面板
飞牛NAS成为家庭私有云热门选择,通过部署宝塔面板,用户可以轻松搭建网站及各类Web应用,如相册、笔记、影视库等。本文介绍如何在飞牛NAS上安装宝塔面板,实现快速配置网站、数据库等服务,特别适合新手操作。
1837 5
在飞牛 NAS 上部署宝塔面板
|
SQL JSON 分布式数据库
实时计算 Flink版产品使用合集之 Flink 与 Debezium 进行数据同步时,遇到 DDL 中文乱码如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
323 0
|
应用服务中间件 nginx
nginx配置gzip压缩
nginx配置gzip压缩
260 1
Python中re模块的正则表达式
【6月更文挑战第2天】了解Python的re模块,它是处理正则表达式的核心工具。正则表达式用于在文本中查找特定模式。本文讨论了re模块的用法和技巧,包括导入模块、匹配、分组、替换文本、编译正则表达式以及使用预定义字符类、量词、锚点等高级功能。通过实例展示了如何在Python中执行这些操作,帮助提升文本处理能力。掌握这些技巧将使你更有效地利用正则表达式解决字符串处理问题。
|
存储 JavaScript
Vue3使用Pinia获取全局状态变量
Vue3使用Pinia获取全局状态变量
554 4
|
Linux Docker 容器
Docker学习重点(2)~docker安装、配置阿里云镜像加速
Docker学习重点(2)~docker安装、配置阿里云镜像加速
728 0