博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C的strncpy和snprintf (是否补充最后字符串结尾)
阅读量:6787 次
发布时间:2019-06-26

本文共 1476 字,大约阅读时间需要 4 分钟。

C里操作字符串很高效,但也很麻烦。

1. char * ( char * destination, const char * source );

最常用的函数,但是却不安全,原因在于,一是要destination有足够的空间,二是要保证source和destination指向的空间没有overlap。

2. int ( char * str, const char * format, ... );

也许要问,这个怎么用于字符串拷贝呢?可以这么用 sprintf(dest, "%s", src); 但是要调用者保证dest有足够的内存存放src。

3. char * ( char * destination, const char * source, size_t num );

比起strcpy,多了个长度的控制。从source拷贝num个字符到destination。如果source里不够num字符怎么办呢?会补充0。

一个典型的用法是:

char buf[MAX];

strncpy(buf, src, MAX-1);

这段代码的本意是,一个长为MAX的buf,最多也就放MAX-1个字符,最后一个位置放‘\0'。因此最多能从src里拷贝MAX-1个字符,如果src里没这么多,剩余的填充0就是了。

但是这样做就安全了么?不是,如果src刚好MAX-1个字符。注意到strncpy只复制了MAX-1个字符,最后一个位置未知,有潜在的隐患。下段代码可以诠释:

#define MAX 4

char buf[MAX];
char* src="123";
memset(buf, 'x', MAX);

// solution 1. memset(buf, 0, MAX);

strncpy(buf, src, MAX-1);
// solution 2. buf[MAX-1] = '\0';

printf("%s\n", buf);

有两个办法可以解决:1. 调用strncpy之前memset为0,有点浪费。2. 在strncpy之后对最后一个字符赋值为0。

都可以,但不够优雅。

4. int ( char *buffer, int buff_size, const char *format, ... );

用作字符串拷贝的用法:

char buf[MAX];

snprintf(buf, sizeof(buf), "%s", src);

即安全,又简洁。

你可能会关心:如果src的长度大于dest(buf)呢?这个是另外一个问题,这里需要的是安全的字符串拷贝,在C语言里,如果一个字符串指针指向的内存没有结尾字符'\0',是非常危险的。

snprintf会把buf的最后一个位置保留为'\0'。

关于返回值:如果当前buf够用,返回实际写入的字符数;如果不够用,返回将要写入的字符数。换句话说,返回值就是传入的字符数目。

假设当前的buf[4].

待写入    实际写入    返回值

12           12     2  够用
123        123   3  够用
1234     123   4  不够用
12345  123   5  不够用

sprintf/snprintf的另外一个用法:

,可以变相的用sprintf来代替:

(str,"%d",value) converts to decimal base. (str,"%x",value) converts to hexadecimal base. (str,"%o",value) converts to octal base.

转载地址:http://hligo.baihongyu.com/

你可能感兴趣的文章
ubuntu配置静态路由
查看>>
[LeetCode] 43.Multiply Strings 字符串相乘
查看>>
PAT NAT 端口映射
查看>>
无人值守linux系统安装
查看>>
在哪里,
查看>>
作业-异常处理
查看>>
解决request中文乱码问题
查看>>
RequireJS入门(二) 转
查看>>
HDU 1573 X问题
查看>>
Linux 下VI文件乱码解决
查看>>
桥牌感悟 1
查看>>
化了妆的祝福 1
查看>>
Chromium Graphics: Video Playback and Compositor
查看>>
父子节点数据统计
查看>>
【HDOJ】3127 WHUgirls
查看>>
Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23)
查看>>
表单中时间格式化
查看>>
求1——10^x-1各个位置的和
查看>>
git:将本地分支与远端分支关联起来
查看>>
$in的方法总结
查看>>