-
strcpy:
strcpy 函数会将源字符串(src)中的字符复制到目标字符串(dest)中,直到遇到源字符串的结束符’ ’。如果目标字符串的空间不足以容纳源字符串,就会导致缓冲区溢出。 -
strncpy:
strncpy 函数会将源字符串(src)中的字符复制到目标字符串(dest)中,最多复制n 个字符。当src 的长度小于n 时,dest 的剩余部分将用空字节填充。但是,如果n 大于src 的长度,strncpy 不会在dest 的末尾添加’ ’结束符,这可能会导致问题。
当src的长度小于n时,strncpy会将src的所有字符复制到dest,然后在dest的剩余部分用空字节(‘ ’)填充,直到复制了n个字符。这意味着如果src的长度小于n,dest字符串将以’ ’结束。
然而,如果n大于或等于src的长度,strncpy会将src的所有字符复制到dest,但不会在dest的末尾添加’ ’结束符。这可能会导致问题,因为如果后续的代码试图访问dest作为一个以’ ’结束的字符串,可能会导致读取未初始化的内存或超出dest的边界。
- strlcpy:
strlcpy 函数是strcpy 函数的一个更安全的版本。在已知目标地址空间大小的情况下,strlcpy 会将源字符串(src)中的字符复制到目标字符串(dest)中,最多复制dsize-1 个字符,并在复制结束后在目标字符串的末尾添加’ ’结束符。这样可以防止缓冲区溢出。
这是一个
#include <string.h>
#include <stdio.h>
int main () {
char buf[5];
char src[10] = "12345678";
// 使用strlcpy
strlcpy(buf, src, sizeof(buf));
printf("%s
", buf); // 输出1234
// 使用strncpy
strncpy(buf, src, sizeof(buf));
printf("%s
", buf); // 输出12345,没有以结束字符结尾
return 0;
}
在这个示例中,使用
总的来说,
这些函数的原型如下:
- strcpy:
#include <string.h> char *strcpy(char *dest, const char *src);
其中,
- strncpy:
#include <string.h> char *strncpy(char *dest, const char *src, size_t n);
其中,
- strlcpy:
#include <string.h> size_t strlcpy(char *dest, const char *src, size_t dsize);
其中,
请注意,这些函数在使用时需要确保目标字符串有足够的空间来存放源字符串,以防止缓冲区溢出。
参考NuttX的代码如下:
FAR char *strcpy(FAR char *dest, FAR const char *src)
{
FAR char *tmp = dest;
while ((*dest++ = *src++) != ' ');
return tmp;
}
FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n)
{
FAR char *ret = dest; /* Value to be returned */
FAR char *end = dest + n; /* End of dest buffer + 1 byte */
/* Copy up n bytes, breaking out of the loop early if a NUL terminator is
* encountered.
*/
while ((dest != end) && (*dest++ = *src++) != ' ')
{
}
/* Note that there may be no NUL terminator in 'dest' */
/* Pad the remainder of the array pointer to 'dest' with NULs */
while (dest != end)
{
*dest++ = ' ';
}
return ret;
}
size_t strlcpy(FAR char *dst, FAR const char *src, size_t dsize)
{
FAR const char *osrc = src;
size_t nleft = dsize;
if (nleft != 0)
{
while (--nleft != 0)
{
if ((*dst++ = *src++) == ' ')
{
break;
}
}
}
if (nleft == 0)
{
if (dsize != 0)
{
*dst = ' ';
}
while (*src++ != ' ');
}
return src - osrc - 1;
}