C中的字符串拷贝问题

来源:互联网 发布:女孩名字网络 编辑:程序博客网 时间:2024/06/11 15:00

1.为什么用strlcpy而不是strcpy、strncpy

 

strcpy

函数原型:

#include <string.h>

char *strcpy(char *dest, constchar *src);

功能:把字符串src中的内容copy到dest中,包括字符串src的结束标志’\0’也一起copy,返回:指向dest的指针。

存在的安全问题:

         当strlen(src)>strlen(dest)时,就会造成内存越界,产生不可预知的错误。

strncpy

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

函数原型:

#include <string.h>

char *strncpy(char *dest, const char *src, size_t n);

功能:把src所指由’\0’结束的字符串的前n个字节复制到dest所指的数组中。

说明:如果src的前n个字节不含’\0’字符,则dest不会以’\0’字符结束。

      如果strlen(src)< n,则以’\0’填充dest直到复制完n个字节。

      src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

返回:指向dest的指针。

存在的问题:

1)当n > dest的长度时,也会造成内存越界,可见strncpy也存在安全问题;

2)如果src的前n个字节不含’\0’字符,则dest不会以’\0’字符结束。此时需手动在dest末尾添加’\0’。

3)如果strlen(src)< n,则以’\0’填充dest直到复制完n个字节。即当n较大而strlen(src)又较小时,影响效率。

  

strlcpy

函数原型:

size_t   strlcpy(char *dst, const char *src, size_t siz);

功能:把src所指由’\0’结束的字符串的前n个字节复制到dest所指的数组中。

返回:strlen(src)

strlcpy优势所在:

1)  解决了上述strncpy存在的问题2和问题3

2)  返回的是strlen(src),可以方便的判断数据是否被截断。

 

strlcpy 并不属于 ANSI C,至今也还不是标准,因此manstrlcpy是找不到的。

strlcpy 来源于 OpenBSD 2.4,之后很多unix-like 系统的 libc 中都加入了 strlcpy 函数,在 FreeBSD、Linux 里面都找到了strlcpy。(Linux使用的是glibc,glibc里面有 strlcpy,则所有的 Linux 版本也都应该有strlcpy)

 

strlcpy的参考代码:

 

综上所述,可利用strncpy替代strcpy来防止缓冲区越界,但是如果还要考虑运行效率的话, strlcpy则是一个更好的方式。

 

2.为什么用snprintf而不是sprintf

 

sprintf

函数原型:

         #include <stdio.h>

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

功能:把格式化的数据写入字符串str

返回:成功返回strlens(str),失败返回-1

存在的问题同strcpy一样,当strlens(str) <格式化字符串的长度时,造成内存越界,产生不可预知的错误。

snprintf

函数原型:

         #include <stdio.h>

         int snprintf(char *str, size_t size,const char *format, ...);

功能:把格式化的字符串的前n个字节写入字符串str

返回:格式化字符串的长度

snprintf优势所在:

1)  提供了写入目标串字符的长度,一定程度上提高了安全性

2)  返回的是格式化字符串的长度而不是strlen(str),可以很方便的判断数据是否被截断。

 

 

 

原创粉丝点击