C语言snprintf函数
int snprintf(char *restrict buf, size_t n, const char * restrict format, ...);
函数说明:最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为n
的话,将不会溢出。
函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。
Result1(推荐的用法)
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[10]={0,};
snprintf(str, sizeof(str), "0123456789012345678");
printf("str=%s\n", str);
return 0;
}
root] /root/lindatest
$ ./test
str=012345678
Result2:(不推荐使用)
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[10]={0, };
snprintf(str, 18, "0123456789012345678");
printf("str=%s\n", str);
return 0;
}
root] /root/lindatest
$ ./test
str=01234567890123456
snprintf函数返回值的测试:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str1[10] ={0, };
char str2[10] ={0, };
int ret1=0,ret2=0;
ret1=snprintf(str1, sizeof(str1), "%s", "abc");
ret2=snprintf(str2, 4, "%s", "aaabbbccc");
printf("aaabbbccc length=%d\n", strlen("aaabbbccc"));
printf("str1=%s,ret1=%d\n", str1, ret1);
printf("str2=%s,ret2=%d\n", str2, ret2);
return 0;
}
[root] /root/lindatest
$ ./test
aaabbbccc length=9
str1=abc,ret1=3
str2=aaa,ret2=9
***************************************************************************
关于sprintf和snprintf的正确使用。
考虑以下有缺陷的例子:
void f(const char *p)
{
char buf[11]={0};
sprintf(buf,"%10s",p); // very dangerous
printf("%sn",buf);
}
不要让格式标记“%10s”误导你。如果p的长度大于10个字符,那么sprintf() 的写操作就会越过buf的边界,从而产生一个缓冲区溢出。
检测这类缺陷并不容易,因为它们只在 p 的长度大于10个字符的时候才会发生。黑客通常利用这类脆弱的代码来入侵看上去安全的系统。
要修正这一缺陷,可以使用函数snprintf()代替函数sprintf()。
函数原型:int snprintf(char *dest, size_t n, const char *fmt, ...);
函数说明: 最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为n的话,将不会溢出。
函数返回值: 若成功则返回存入数组的字符数,若编码出错则返回负值。
推荐的用法:
void f(const char *p)
{
char buf[11]={0};
snprintf(buf, sizeof(buf), "%10s", p); // 注意:这里第2个参数应当用sizeof(str),而不要使用硬编码11,也不应当使用sizeof(str)-1或10
printf("%sn",buf);
}
**************************************************************************
众所周知,sprintf不能检查目标字符串的长度,可能造成众多安全问题,所以都会推荐使用snprintf.
snprintf(_snprintf)的声明是这样的
int _snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned.
If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned.
If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned.
最常见的错误用法有:
1.
char sa[256]={0};
_snprintf(sa,sizeof(sa),"%s",sb);
//错误原因:当sb的长度>=256的时候,sa将没有'\0'结尾
2.
char sa[256];
_snprintf(sa,sizeof(sa)-1,"%s",sb);
//错误原因:当sb的长度>=255的时候,sa将没有'\0'结尾,忘记给sa初始化
3.
char sa[256];
_snprintf(sa,sizeof(sa)-1,"%s",sb);
sa[sizeof(sa)]=0;
//错误原因:最后一行数组越界
正确的用法
1. //推荐用法
char sa[256];
sa[sizeof(sa)-1]=0;
_snprintf(sa,sizeof(sa),"%s",sb);
if(sa[sizeof(sa)-1]!=0)
{
printf("warning:string will be truncated");
sa[sizeof(sa)-1]=0;
}
2.
char sa[256]={0};
int result = _snprintf(sa,sizeof(sa),"%s",sb);
if(result==sizeof(sa) || result<0)
{
printf("warning:sting will be truncated");
sa[sizeof(sa)-1]=0;
}
C语言snprintf函数的更多相关文章
- [C/C++基础] C语言常用函数sprintf和snprintf的使用方法
Sprintf 函数声明:int sprintf(char *buffer, const char *format [, argument1, argument2, …]) 用途:将一段数据写入以地址 ...
- 【C语言天天练(十三)】printf、fprintf、sprintf和snprintf函数
#include <stdio.h> int printf(const char *format, ...); int fprintf(FILE *stream, const char * ...
- C语言pow函数编写
C语言pow函数编写 #include<stdio.h> double chaoba(double f,double q); //声明自定义函数 void main(void) { dou ...
- C语言-自定义函数
C语言自定义函数 --1-- 自定义函数定义 1.1 无参无返回值函数 1.2 无参有返回值函数 1.3 有参无返回值函数 1.4 有参有返回值函数 --2-- 函数的参数 2.1 形式参数介绍和使用 ...
- C语言printf()函数:格式化输出函数
C语言printf()函数:格式化输出函数 头文件:#include <stdio.h> printf()函数是最常用的格式化输出函数,其原型为: int printf( char ...
- C语言的函数
"函数"在英文的翻译是"function",无论在自然科学还是计算机科学都是这个词,而"function"的本意是"功能" ...
- c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)
C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...
- Go语言示例-函数返回多个值
Go语言中函数可以返回多个值,这和其它编程语言有很大的不同.对于有其它语言编程经验的人来说,最大的障碍不是学习这个特性,而是很难想到去使用这个特性. 简单如交换两个数值的例子: package mai ...
- 【学习笔记】【C语言】函数
一. 什么是函数 任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”.所以,你可以说C语言程序是由函数构成的. 比如你用C语言编写了一 ...
随机推荐
- 常用js函数
1.获得元素到页面的绝对距离 function getPos(obj) { var pos = {left:0, top:0}; while (obj) { pos.left += obj.offse ...
- jsonp 使用示例
客户端: <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>< ...
- Jquery操作单选按钮(Radio)的取值赋值实现代码
1.获取选中值,三种方法都可以: $('input:radio:checked').val(); $("input[type='radio']:checked").val(); $ ...
- 动画讲解 Eclipse 常用快捷键
Eclipse有强大的编辑功能, 工欲善其事,必先利其器, 掌握Eclipse快捷键,可以大大提高工作效率. 小坦克我花了一整天时间, 精选了一些常用的快捷键操作,并且精心录制了动画, 让你一看就会. ...
- 点评VHDL语言
(1)VHDL的描述风格及语法十分类似于一般的计算机高级语言,但是它是一种硬件描述语言.学好VHDL的关键是充分理解VHDL语句和硬件电路的关系.编写VHDL,就是在描述一个电路,我们写完一段程序后, ...
- ORA-01033 ORA-01109 ORA-01034 ORA-12514 ORA-24324 ORA-01041 ORA-01157 ORA-01110
客户数据库挂掉了 在plsql客户端使用普通账号登录时提示如下错误 因为好久没弄数据库了,慌了一小下. 接下来搜索过往的知识,回忆.在cli下输入了以下命令 sqlplus system/system ...
- LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the contex异常的原因
eclipse里面启动tomcat报这个错误的原因是由于jar包冲突了,在我的项目里面引入了jar包,但是我的工程里面有这个jar包的两个工程,都被导入到同一个项目里面了,导致不知道该去用哪一个类,所 ...
- Multi-Die系统介绍
一个典型的存储系统一般是有几片NAND存储器组成的.一般会使用8-bit的总线,用来将不同的存储器与控制器进行连接,如图2.32所示.一个系统中多片NAND的存储系统可以提高存储容量,同时还可以提高读 ...
- 结论: blocking_query 是当前堵塞其他会话正在运行的SQL.而不是原始堵塞SQL
查看当前session线程号 mysql> select connection_id(); +-----------------+ | connection_id() | +---------- ...
- sed 变量替换 把m.txt文件中的$i替换成$j
zabbix:/root/zabbix# cat a1.sh for j in {1..48} do sed "s/\$i/$j/g" m.txt >>tmp.txt ...