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

相关文章

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

Linux磁盘分区、格式化和挂载方式

《Linux磁盘分区、格式化和挂载方式》本文详细介绍了Linux系统中磁盘分区、格式化和挂载的基本操作步骤和命令,包括MBR和GPT分区表的区别、fdisk和gdisk命令的使用、常见的文件系统格式以... 目录一、磁盘分区表分类二、fdisk命令创建分区1、交互式的命令2、分区主分区3、创建扩展分区,然后

Linux中chmod权限设置方式

《Linux中chmod权限设置方式》本文介绍了Linux系统中文件和目录权限的设置方法,包括chmod、chown和chgrp命令的使用,以及权限模式和符号模式的详细说明,通过这些命令,用户可以灵活... 目录设置基本权限命令:chmod1、权限介绍2、chmod命令常见用法和示例3、文件权限详解4、ch

Linux内核之内核裁剪详解

《Linux内核之内核裁剪详解》Linux内核裁剪是通过移除不必要的功能和模块,调整配置参数来优化内核,以满足特定需求,裁剪的方法包括使用配置选项、模块化设计和优化配置参数,图形裁剪工具如makeme... 目录简介一、 裁剪的原因二、裁剪的方法三、图形裁剪工具四、操作说明五、make menuconfig

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

Linux使用nohup命令在后台运行脚本

《Linux使用nohup命令在后台运行脚本》在Linux或类Unix系统中,后台运行脚本是一项非常实用的技能,尤其适用于需要长时间运行的任务或服务,本文我们来看看如何使用nohup命令在后台... 目录nohup 命令简介基本用法输出重定向& 符号的作用后台进程的特点注意事项实际应用场景长时间运行的任务服

什么是cron? Linux系统下Cron定时任务使用指南

《什么是cron?Linux系统下Cron定时任务使用指南》在日常的Linux系统管理和维护中,定时执行任务是非常常见的需求,你可能需要每天执行备份任务、清理系统日志或运行特定的脚本,而不想每天... 在管理 linux 服务器的过程中,总有一些任务需要我们定期或重复执行。就比如备份任务,通常会选在服务器资

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

Linux限制ip访问的解决方案

《Linux限制ip访问的解决方案》为了修复安全扫描中发现的漏洞,我们需要对某些服务设置访问限制,具体来说,就是要确保只有指定的内部IP地址能够访问这些服务,所以本文给大家介绍了Linux限制ip访问... 目录背景:解决方案:使用Firewalld防火墙规则验证方法深度了解防火墙逻辑应用场景与扩展背景: