strncpy并使用sizeof复制最大字符

时间:2009-07-24 09:58:45

标签: c strncpy

我正在使用以下代码

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元素中吗?

非常感谢任何信息,

7 个答案:

答案 0 :(得分:13)

strncpy null - 如果它截断字符串,则终止目标。如果必须使用strncpy,则需要确保结果终止,例如:

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

BSD的strlcpy()等通常被认为是优越的:

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

答案 1 :(得分:4)

你的想法:

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

无效,因为您将在非终止字符串上调用strlen()

答案 2 :(得分:4)

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

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

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

char buffer[bufferSize + 1];
strncpy( buffer, source, bufferSize );
*(buffer + bufferSize ) = 0;

答案 3 :(得分: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

答案 4 :(得分:1)

1)从cplusplus.com:“没有空字符隐式附加到目标的末尾,因此如果源中的C字符串的长度小于num,则目标将仅以空值终止。”因此,如果您需要将字符串设置为空终止,则需要执行以下操作:

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

执行此操作的一个好方法是为strncpy编写一个包装函数,以确保字符串终止。

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

答案 5 :(得分:1)

以与strncpy相同的方式使用strlcpy。无需在第3个参数中执行size-1

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

答案 6 :(得分:0)

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