7

我正在使用下面的代码

char call[64] = {'\0'} /* clean buffer */
strncpy(call, info.called, sizeof(call));

我总是使用 sizeof 作为目标来保护溢出,以防源大于目标。这样我可以防止缓冲区溢出,因为它只会复制目的地可以处理的尽可能多的内容。

但我现在想知道它是否会终止目的地。

几个案例。

1) 如果源更大。我可以这样做:

call[strlen(call) - 1] = '\0'; /* insert a null at the last element.*/

2)如果源小于目标。call 是 64 个字节,我复制了 50 个字节,因为这是源的大小。它会自动将 null 放在 51 元素中吗?

非常感谢您提供的任何信息,

4

7 回答 7

15

strncpy如果它截断字符串,则不会以空值终止目标。如果必须使用strncpy,则需要确保结果终止,例如:

strncpy(call, info.called, sizeof(call) - 1);
call[sizeof(call) - 1] = '\0';

BSDstrlcpy()等等,通常被认为是优越的:

http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy

于 2009-07-24T10:03:01.097 回答
7

如果源的长度小于作为第三个参数传递的最大数量 strncpy 将终止目标,否则 - 不是。

如果源的长度等于或大于目标的长度 - 处理它是您的问题。像你建议的那样做 - 调用 strlen() - 将不起作用,因为缓冲区不会以空值终止,你会遇到未定义的行为。

您可以分配更大的缓冲区:

char buffer[bufferSize + 1];
strncpy( buffer, source, bufferSize );
*(buffer + bufferSize ) = 0;
于 2009-07-24T10:02:46.543 回答
4

你的想法:

call[strlen(call) - 1] = '\0';

不起作用,因为您将调用strlen()未终止的字符串

于 2009-07-24T10:01:33.610 回答
1

但我现在想知道它是否会终止目的地。

不,strncpy 不承诺目标字符串将以空值终止。

char tar[2]={0,0};
char bar="AB";
strncpy(tar,bar,2);
// result tar[0]=='A'; tar[1]=='B'

为了使它正确,您应该使用:

strncpy(traget,string,sizeof(target)-1);
target[sizeof(target)-1]=0
于 2009-07-24T10:03:57.867 回答
1

1)来自cplusplus.com:“没有空字符隐式附加到目标末尾,因此只有当源中 C 字符串的长度小于 num 时,目标才会以空字符结尾。” 因此,如果您需要以空字符结尾的字符串,则需要执行以下操作:

call[sizeof(call) - 1] = '\0';

这样做的一个好方法是编写一个包装函数,strncpy它始终确保字符串被终止。

2) 如果源比目标短,目标将以空值终止。

于 2009-07-24T10:04:15.010 回答
1

只需使用 strlcpy() 而不是 strncpy()。您必须检查它是否在所有平台上都可用。早期版本的 linux 可能没有它。

于 2014-05-26T00:44:56.687 回答
1

以与 strncpy 相同的方式使用 strlcpy。不需要在第三个参数中做 size-1

即: strncpy(call, info.called, sizeof(call)-1);strlcpy(call, info.called, sizeof(call));

于 2020-09-08T06:31:45.857 回答