1. 背景


好多人已经知道利用strncpy替代strcpy来防止缓冲区越界。
但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式。

2. strcpy


strcpy 是依据 /0 作为结束判断的,如果 to 的空间不够,则会引起 buffer overflow。
strcpy 常规的实现代码如下:

char * strcpy(char *to, const char *from)
{
char *save = to; for (; (*to = *from) != '/0'; ++from, ++to);
return(save);
}

但通常,我们的 from 都来源于用户的输入,很可能是非常大的一个字符串,因此 strcpy 不够安全。

2. strncpy


在 ANSI C 中,strcpy 的安全版本是 strncpy

char *strncpy(char *s1, const char *s2, size_t n);

但 strncpy 其行为是很诡异的(不符合我们的通常习惯)。标准规定 n 并不是 sizeof(s1),而是要复制的 char 的个数。一个最常见的问题,就是 strncpy 并不帮你保证以'/0'结束。

char buf[8];
strncpy( buf, "abcdefgh", 8 );

看这个程序,buf 将会被 “abcdefgh” 填满,但却没有 '/0' 结束符了。
另外,如果 s2 的内容比较少,而 n 又比较大的话,strncpy 将会把之间的空间都用 '/0' 填充。这又出现了一个效率上的问题,如下:

char buf[80];
strncpy( buf, "abcdefgh", 79 );

上面的 strncpy 会填写 79 个 char,而不仅仅是 “abcdefgh” 本身。
strncpy 的标准用法为:(手工写上 '/0'

strncpy(path, src, sizeof(path) - 1);
path[sizeof(path) - 1] = '/0';
len = strlen(path);

3. strlcpy


// Copy src to string dst of size siz. At most siz-1 characters
// will be copied. Always NUL terminates (unless siz == 0).
// Returns strlen(src); if retval >= siz, truncation occurred.
size_t strlcpy(char *dst, const char *src, size_t siz);

使用 strlcpy,就不需要我们去手动负责'/0' 了,仅需要把 sizeof(dst) 告之 strlcpy 即可:

strlcpy(path, src, sizeof(path));
len = strlen(path);
if ( len >= sizeof(path) )
printf("src is truncated.");

并且 strlcpy 传回的是 strlen(str),因此我们也很方便的可以判断数据是否被截断。

[* 一点点历史 *]

strlcpy 并不属于 ANSI C,至今也还不是标准。
strlcpy 来源于 OpenBSD 2.4,之后很多 unix-like 系统的 libc 中都加入了 strlcpy 函数,我个人在 FreeBSD、Linux 里面都找到了 strlcpy。(Linux使用的是 glibc,glibc里面有 strlcpy,则所有的 Linux 版本也都应该有 strlcpy)
但 Windows 下是没有 strlcpy 的,对应的是strncpy和memset函数
本篇文章来源于 Linux公社网站(www.linuxidc.com)
原文链接:http://www.linuxidc.com/Linux/2012-06/61893.htm

(C)strcpy ,strncpy与strlcpy的更多相关文章

  1. C语言strcpy,strncpy和strlcpy讲解

    前言 C风格的字符串处理函数有很多,如strcpy().strcat()等等. strcpy与strcat char* strcpy (char* dest, const char* src); ch ...

  2. (C)strcpy ,strncpy和strlcpy的基本用法

    好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. strcpy strcpy 是依据 /0 作为结束判断的, ...

  3. C语言中函数strcpy ,strncpy ,strlcpy的用法【转】

    转自:http://blog.chinaunix.net/uid-20797562-id-99311.html strcpy ,strncpy ,strlcpy的用法好多人已经知道利用strncpy替 ...

  4. C语言中函数strcpy ,strncpy ,strlcpy的用法

    strcpy ,strncpy ,strlcpy的用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. s ...

  5. Linux C中strcpy , strncpy , strlcpy 的区别

    strcpy ,strncpy ,strlcpy的用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. s ...

  6. strcpy、strncpy、strlcpy的区别

  7. C语言——常用标准输入输出函数 scanf(), printf(), gets(), puts(), getchar(), putchar(); 字符串拷贝函数 strcpy(), strncpy(), strchr(), strstr()函数用法特点

    1 首先介绍几个常用到的转义符 (1)     换行符“\n”, ASCII值为10: (2)     回车符“\r”, ASCII值为13: (3)     水平制表符“\t”, ASCII值为 9 ...

  8. strcpy/strncpy/strcpy_s比较

    转载自:http://blog.csdn.net/caomiao2006/article/details/4766416 strcpy()是依据源串的/0作为结束判断的,不检查copy先的Buffer ...

  9. C++ strcpy strcpy_s strncpy strlcpy

    strncpy的用法:它与strcpy的不同之处就在于复制n个字符,而不是把所有字符拷贝(包括结尾'\0'). 函数原型:char * strncpy(char *dst,const char * s ...

随机推荐

  1. C 语言中的 fgets()

    转自:http://blog.csdn.net/daiyutage/article/details/8540932 原型: char *  fgets(char * s, int n,FILE *st ...

  2. EMD距离

    一.场景介绍   最近在研究一个场景:图片质量评分,给一张图片一个预测的分数.   里面提到了用 EMD(Earth Mover’s Distance)算法来评估两张图片之间的分布距离.下面主要讲解下 ...

  3. C++ 使用成员初始化列表的一个小坑

    注意在成员列表中初始化的顺序并不是列表顺序 而是: 在类中声明的顺序! EventLoop::EventLoop() :looping(false), quit(false),_tid(curThre ...

  4. [bzoj3308]九月的咖啡店_欧拉筛素数_费用流

    bzoj-3308 九月的咖啡店 题目大意:深绘里在九份开了一家咖啡让,如何调配咖啡民了她每天的头等大事我们假设她有N种原料,第i种原料编号为i,调配一杯咖啡则需要在这里若干种兑在一起.不过有些原料不 ...

  5. Tomcat7/8开启WebDAV的支持

    WebDAV是一种超文本传输协议,Tomcat默认是支持WebDAV的,且默认为禁用状态. 更多详细信息,请参考: https://zh.wikipedia.org/wiki/WebDAV http: ...

  6. axis2调用WSDL接口

    public static JSONObject sendWsdl(String url,String xmlStr){ JSONObject res=new JSONObject(); try { ...

  7. Go -- PipleLine

    1.pipeline的产生 从一个现象说起,有一家咖啡吧生意特别好,每天来的客人络绎不绝,客人A来到柜台,客人B紧随其后,客人C排在客人B后面,客人D排在客人C后面,客人E排在客人D后面,一直排到店面 ...

  8. Gas Station,转化为求最大序列的解法,和更简单简单的Jump解法。——贪心、转化

    Gas Station There are N gas stations along a circular route, where the amount of gas at station i is ...

  9. 【转载】读懂IL代码就这么简单 (一)

    一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解IL代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉 ...

  10. C# json反序列化 对象中嵌套数组 (转载) 可能会导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

    C# json反序列化 对象中嵌套数组 (转载)   看图: 这里可以看到是二层嵌套!!使用C#如何实现?? 思路:使用list集合实现 → 建立类 → list集合 → 微软的   Newtonso ...