为什么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

相关文章

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

深度解析Spring Boot拦截器Interceptor与过滤器Filter的区别与实战指南

《深度解析SpringBoot拦截器Interceptor与过滤器Filter的区别与实战指南》本文深度解析SpringBoot中拦截器与过滤器的区别,涵盖执行顺序、依赖关系、异常处理等核心差异,并... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编