我正在使用以下代码
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元素中吗?
非常感谢任何信息,
答案 0 :(得分:13)
strncpy
不 null - 如果它截断字符串,则终止目标。如果必须使用strncpy
,则需要确保结果终止,例如:
strncpy(call, info.called, sizeof(call) - 1);
call[sizeof(call) - 1] = '\0';
BSD的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的早期版本可能没有它。