先来看一下msdn上的函数原型和对其参数的解释
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
Parameters
strDestination
Location of the destination string buffer.
numberOfElements
Size of the destination string buffer in char units for narrow and multi-byte functions, and wchar_t units for wide functions.
strSource
Null-terminated source string buffer.
msdn上说第二个参数 numberOfElements 是目标缓冲区大小。
那么这个大小到底应该设置为多大?相信很多人都有同样的困惑,下面用代码测试一下几种情况。
int _tmain(int argc, _TCHAR* argv[])
{
char dest[10] = {0};
char src[] = "12345";
printf_s("dest string size: %d\n", sizeof(dest)); // 10
printf_s("src string size: %d\n", strlen(src)); // 6
//strcpy_s(dest, 5, src); // 报错:5sizeof(dest)
getchar();
return 0;
}
从测试的情况可能得出结论:
使用 strcpy_s 要满足以下条件:strlen(src) < numberOfElements <= sizeof(dest)
这个条件说明要 strlen(src) < sizeof(dest) ,即目标缓冲区的大小一定要大于源字符串的长度
为什么右边有等号左边没有?因为 src 大多情况下是字符串而不是字符数组,而字符串是包含了结束符 null 的,所以在 strcpy_s 的时候要考虑进去。
其实,还有更加安全的方式:用 strncpy_s
int _tmain(int argc, _TCHAR* argv[])
{
char dest[6] = {0};
char src[] = "1234567890";
printf_s("dest string size: %d\n", sizeof(dest)); // 6
printf_s("src string size: %d\n", strlen(src)); // 10
strncpy_s(dest, 6, src, 5); // ok
getchar();
return 0;
}
上述代码中,尽管源字符串长度大于目标缓冲区的大小,也不会报错,但是要设置好 strncpy_s 第二和第四个参数的值。简单的说,把 strncpy_s 的第二个参数设置为目标缓冲区的大小,把第四个参数设置为第二个参数的值减 1 就可以了,当然,也可以设置为其他合理的值,比如msdn上面提到的 _TRUNCATE ,这些在msdn上都有详细的说明,大家可以自己去看一看。
所以,建议大家用 strncpy_s
参考:
strncpy_s, _strncpy_s_l, wcsncpy_s, _wcsncpy_s_l, _mbsncpy_s, _mbsncpy_s_l
strcpy_s, wcscpy_s, _mbscpy_s
版权声明
如需转载请注明来源和作者,谢谢!!
本文链接:https://blog.csdn.net/ShiQW5696/article/details/80676290