我知道网上有很多答案说一个比另一个更好但是我对strncpy()
的理解更好,因为它可以防止系统中不必要的崩溃'\0'
。正如许多人所说,这是非常防御性的。
我已经浏览了这个链接:Why should you use strncpy instead of strcpy?
让我们说:
char dest[5];
char src[7] = "Hello";
strncpy(dest, src, sizeof(dest)-1);
通过这种实现(密钥为sizeof(dest)-1
,它总是为'\0'
添加空间提供空间),即使目标有一个截断的字符串,也不总是更安全strncpy()
代替strcpy()
?换句话说,我试图了解何时想要strcpy()
使用strncpy()
?
答案 0 :(得分:8)
不是更好。与普遍看法相反,strncpy
没有被创建来替换strcpy
或者是它的安全版本。当源字符串大于num
参数时,它无法使字符串终止,因此您必须手动执行此操作。像这样:
strncpy(dst, src, num);
dst[num - 1] = 0;
这需要2行来实现1个简单的目标,开发人员很容易忘记第二个目标。
除此之外,它始终会写num
个字符(必要时附加0
个},无论字符串的大小如何dst
是num
小而strncat
很大。
使用dst[0];
strncat(dst, src, num);
修复了编写额外字符的第二个问题,但仍然强迫你写2行:
snprintf(dst, size, "%s", src);
函数strlcpy
解决了这两个问题,但它不是C标准库函数,所以不要使用它。
正确的选择是snprintf
,保证null终止字符串并且只写入必要数量的字符,即使它意味着截断源字符串。
{{1}}
答案 1 :(得分:3)
在C中,strncpy
优于strcpy
,当源大于目的地时,它不会溢出缓冲区。
strncpy
的缺点是,当源大于目标时,不会使用\0
终止缓冲区。因此,每次调用strncpy
必须后跟一个终止缓冲区的语句,例如
strncpy(dst, src, n);
dst[n-1]='\0';
用户Eugene Sh指出,对于防御性编程,必须使用strlcpy
:" strlcpy()获取目标缓冲区的完整大小
保证NUL终止。"
答案 2 :(得分:1)
在C ++中,使用std::string
而不是c风格的字符串,除非在特定区域中的性能至关重要,在这种情况下,性能测试以查看它是否超过可忽略的差异。当您事先知道尺寸时,可以使用std::string::reserve
来最小化分配。
在我看来,85%的错误都是由c风格的字符串引起的。 std::string
更安全,不易出错。
在C中,您将无法使用std::string
。
如果你必须使用c风格的字符串,那么我更喜欢strncpy
,因为至少它要求大小并让你考虑大小,而不仅仅是溢出。