在使用strncpy, snprintf, strncatd等函数时,size到底要定义多大呢?
一、strncpy
char *strncpy(char *dst, const char *src, size_t n);
功能:
1)把src所指由\0结束的字符串的前n个字节复制到dest所指的数组中。
2)返回指向dest的指针(该指向dest的最后一个元素)
说明:
1)如果src的前n个字节不含\0,则结果不会以\0字符结束(strncpy 并不帮你保证 \0 结束。)。如果src的长度小于n个字节,则以\0填充dst直到复制完n个字节。
2)src和dst所指内存区域不可以重叠,且dest必须有足够的空间来容纳src的字符串。
标准用法:
char buf[80]; strncpy(buf, src, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; //手工写上 \0
问题分析举例1:
char buf[8]; strncpy( buf, "abcdefgh", sizeof(buf) );
这个程序里buf 将会被 "abcdefgh" 填满,但却没有 \0 结束符了。
问题分析举例2:
char buf[80]; strncpy( buf, "abcdefgh", sizeof(buf)-1 );
如果 src的内容比较少,而 n 又比较大的话,strncpy 将会把之间的空间都用 \0 填充。这就出现了一个效率上的问题,上面的 strncpy 会填写 79 个 char,而不仅仅是 "abcdefgh" 本身。在对性能要求高的地方使用时,需要考虑该问题。
二、snprintf
int snprintf(char *str, size_t size, const char *format, ...);
功能:
将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
说明:
1)如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');
2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度。
3)返回值是“如果有足够空间存储,所应能输出的字符数(不包括字符串结尾的'\0')”,例如可以写入的字符串是"0123456789ABCDEF"共16位,但是size限制了是10,这样 snprintf() 的返回值将会是16而不是10。
举例:
char rate[255] = { 0 }; snprintf(rate, sizeof(rate), "%d", 123);
这里size不需要-1,它是字符串拷贝唯一一个会截断并且会添'\0'的函数。
三、strncat
char *strncat(char *dest, const char *src, size_t n);
功能:
把src所指字符串的前n个字符添加到dest所指字符串的结尾处,从而实现字符串的连接(原dest所指字符串结尾的'\0'将被覆盖)。如果src字符串长度大于n个字节,那么strncat只截取n个字节,并且会在字符串末尾添加'\0'
说明:
src和dest所指内存区域不可以重叠,并且dest必须有足够的空间来容纳src的字符串。
返回值:
返回指向dest的指针。
标准用法:
char buf[256] = { 0 }; strncat(buf,"test",sizeof(buf)-strlen(buf)-1); //如果已知buf长度最好将strlen替代掉,耗性能。
其中sizeof(buf)表示buf的总空间,strlen(buf)表示已经使用的空间,则sizeof(buf)-strlen(buf)-1表示剩余空间大小减一(预留\0的位置,但不需要手动填充)。如果该长度比src长很多,不会像strncpy那样将\0填充dst直到复制完n个字节。
四、其他
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
返回值:
成功则返回输出字节数个数,失败返回0。
若成功会自动补上'\0'
默认输出最大字节为max-1,因此传入参数时,sizeof 不用再减1。
标准用法:
ret = strftime(buf, sizeof(buf), "%Y-%m-%d", tm); if(ret == 0){ printf("failed\n"); }
原文地址:https://www.cnblogs.com/realjimmy/p/12974472.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Debug LinkedList
- Java对象公约
- 【Flutter 专题】96 图解 Draggable + DragTarget 基本拖拽效果
- Spring 基于注解(annotation)的配置之@Autowired注解
- 人心易变,这段有趣的C代码也一样!!!
- matplotlib绘制常见统计图形(一)
- python与安全(二)格式化字符串和Flask session
- ROS2机器人笔记20-07-24
- Postgresql 渗透利用总结
- Spring 基于注解(annotation)的配置之@Required注解
- 由一个系统激活工具引起的一次简单测试
- Golang channel 快速入门
- 潘石屹用Python解决100个问题 | 素数
- Spring 自动装配模式之构造函数装配方式
- 安全狗 {safedog} 最新版注入bypass