难道不比strcpy好吗?

时间:2017-04-19 15:33:11

标签: c strcpy strncpy

我知道网上有很多答案说一个比另一个更好但是我对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()

3 个答案:

答案 0 :(得分:8)

不是更好。与普遍看法相反,strncpy没有被创建来替换strcpy或者是它的安全版本。当源字符串大于num参数时,它无法使字符串终止,因此您必须手动执行此操作。像这样:

strncpy(dst, src, num);
dst[num - 1] = 0;

这需要2行来实现1个简单的目标,开发人员很容易忘记第二个目标。

除此之外,它始终会写num个字符(必要时附加0个},无论字符串的大小如何dstnum小而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,因为至少它要求大小并让你考虑大小,而不仅仅是溢出。