为什么snprintf比sprintf更安全 (另外,请注意, Windows和Linux中的snprintf函数有区别

2024-01-04 05:18

本文主要是介绍为什么snprintf比sprintf更安全 (另外,请注意, Windows和Linux中的snprintf函数有区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

       在前面的博文中,我们深入分析了strcpy和strncpy, 并指出,谁要再用strcpy, 谁就是流氓, 下面,我们来看看与之类似的sprintf和snprintf.  实际上, 在VC++6.0中,用的是_snprintf, 为了方便起见,叙述的时候,我还是用snprintf.


       看下面测程序(设data为某一情况下产生的数据):

#include <iostream>#include <cstring>#define snprintf _snprintfusing namespace std;int main()char str[10] = {0}; char *data = "ab"sprintf(str, "debug : %s", data); cout << str << endlreturn 0;}

      我运行上述程序, 非常侥幸, 没有错误。 但是, 我说了,data是某种情况下产生的数据,所以长度有可能不一定,要是万一data在极端情况下比较长,那会怎么样呢?直接上代码:

#include <iostream>#include <cstring>#define snprintf _snprintfusing namespace std;int main()char str[10] = {0}; char *data = "abcdefg"sprintf(str, "debug : %s", data); cout << str << endlreturn 0;}
      我运行了一下程序,发现程序可以编译过,但是在运行期间崩溃。要是在大系统中,用户肯定会找你麻烦,你的产品何谈竞争力?


      可以做如下修改:

#include <iostream>#include <cstring>#define snprintf _snprintfusing namespace std;int main()char str[10] = {0}; char *data = "abcdefg"snprintf(str, sizeof(str) - 1, "debug : %s", data); cout << str << endlreturn 0;}
     这样就安全了,和strncpy非常类似。


     另外,需要特别注意的是: Windows和Linux中的snprintf函数有区别, 在linux代码中,经常见到snprintf(str, sizeof(str), "...")这样的用法, 为什么这里不是sizof(str) - 1呢?

我们看看Windows下这么用会怎样:

#include <iostream>#include <cstring>#define snprintf _snprintfusing namespace std;int main()char str[10] = {0}; char *data = "abcdefgddddddddddddddddddddd"snprintf(str, sizeof(str), "debug : %s", data); cout << str << endlreturn 0;}
     我运行的时候,程序没有崩溃,算是万幸。 但结果乱码。看来,没有自动在str最后加'\0',  在linux中, 就安全了, 会自动补哈, 所以永远不会越界。


     总结一下: 

     1. Linux中, 对于snprintf, 用sizeof(str),  最后会自动加'\0', 比strncpy更安全省事。

     2. Windows中, 就把snprintf和strncpy理解为类似的, 要用sizeof(str) - 1, 需要注意最后的'\0', 当然啦,你可以在每次用strncpy之前,利用memset将串清零, 这样比较好。VC++6.0中的_snprintf(snprintf)并没有按要求实现, 晕。

      


           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述

这篇关于为什么snprintf比sprintf更安全 (另外,请注意, Windows和Linux中的snprintf函数有区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/568270

相关文章

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Windows 上如果忘记了 MySQL 密码 重置密码的两种方法

《Windows上如果忘记了MySQL密码重置密码的两种方法》:本文主要介绍Windows上如果忘记了MySQL密码重置密码的两种方法,本文通过两种方法结合实例代码给大家介绍的非常详细,感... 目录方法 1:以跳过权限验证模式启动 mysql 并重置密码方法 2:使用 my.ini 文件的临时配置在 Wi

Python正则表达式语法及re模块中的常用函数详解

《Python正则表达式语法及re模块中的常用函数详解》这篇文章主要给大家介绍了关于Python正则表达式语法及re模块中常用函数的相关资料,正则表达式是一种强大的字符串处理工具,可以用于匹配、切分、... 目录概念、作用和步骤语法re模块中的常用函数总结 概念、作用和步骤概念: 本身也是一个字符串,其中

JAVA保证HashMap线程安全的几种方式

《JAVA保证HashMap线程安全的几种方式》HashMap是线程不安全的,这意味着如果多个线程并发地访问和修改同一个HashMap实例,可能会导致数据不一致和其他线程安全问题,本文主要介绍了JAV... 目录1. 使用 Collections.synchronizedMap2. 使用 Concurren

Linux命令之firewalld的用法

《Linux命令之firewalld的用法》:本文主要介绍Linux命令之firewalld的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux命令之firewalld1、程序包2、启动firewalld3、配置文件4、firewalld规则定义的九大

Windows Docker端口占用错误及解决方案总结

《WindowsDocker端口占用错误及解决方案总结》在Windows环境下使用Docker容器时,端口占用错误是开发和运维中常见且棘手的问题,本文将深入剖析该问题的成因,介绍如何通过查看端口分配... 目录引言Windows docker 端口占用错误及解决方案汇总端口冲突形成原因解析诊断当前端口情况解

Linux之计划任务和调度命令at/cron详解

《Linux之计划任务和调度命令at/cron详解》:本文主要介绍Linux之计划任务和调度命令at/cron的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux计划任务和调度命令at/cron一、计划任务二、命令{at}介绍三、命令语法及功能 :at

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文