strncpy 并使用 sizeof 复制最大字符数
我使用下面的代码,
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 元素吗?
非常感谢您提供任何信息,
I am using the code below
char call[64] = {'\0'} /* clean buffer */
strncpy(call, info.called, sizeof(call));
I always use the sizeof for the destination for protecting a overflow, incase source is greater than the destination. This way I can prevent a buffer overflow as it will only copy as much as the destination can handle.
But I am now wondering if it will null terminate the destination.
A couple of cases.
1) If the source is greater.
I could do this:
call[strlen(call) - 1] = '\0'; /* insert a null at the last element.*/
2) If the source is less than the destination.
call is 64 bytes, and I copy 50 bytes as that is the size of the source. Will it automatically put the null in the 51 element?
Many thanks for any information,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果
strncpy
截断字符串,则它不会以 null 终止目标。 如果必须使用strncpy
,则需要确保结果被终止,例如:BSD的
strlcpy()
等,通常被认为是优越的:http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy
strncpy
will not null-terminate the destination if it truncates the string. If you must usestrncpy
, you need to ensure that the result is terminated, something like:BSD's
strlcpy()
, among others, is generally considered superior:http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy
如果源的长度小于作为第三个参数传递的最大数量,strncpy 将以 null 终止目标,否则 - 不会。
如果源的长度等于或大于目标的长度 - 处理它就是你的问题。 像您建议的那样 - 调用 strlen() - 将不起作用,因为缓冲区不会以 null 终止,并且您将遇到未定义的行为。
您可以分配更大的缓冲区:
If the source's length is less than the max number passed as third parameter strncpy will null-terminate the destination, otherwise - not.
If the source is equal or greater in length than the destination - it's your problem to deal with it. Doing like you suggest - calling strlen() - will not work since the buffer will be not null-terminated and you'll run into undefined behaviour.
You could allocate a bigger buffer:
您的想法:
行不通,因为您将在非终止字符串上调用
strlen()
Your idea:
would not work, as you would be calling
strlen()
on a non-terminated string1) 来自cplusplus.com:“没有隐式附加空字符到目的地的末尾,因此只有当源中的 C 字符串的长度小于 num 时,目的地才会以空终止。” 因此,如果您需要字符串以 null 终止,则需要执行以下操作:
实现此目的的一个好方法是为
strncpy
编写一个包装函数,该函数始终确保字符串终止。2) 如果源比目标短,则目标将以空终止。
1) From cplusplus.com: "No null-character is implicitly appended to the end of destination, so destination will only be null-terminated if the length of the C string in source is less than num." So you if you need your string to be null-terminated, you need to do this:
A good way to do this would be to write a wrapper function for
strncpy
that always makes sure the string is terminated.2) If the source is shorter than the destination, the destination will be null-terminated.
不,strncpy 不承诺目标字符串将以 null 结尾。
为了使其正确,您应该使用:
No, strncpy does not promise that target string would be null terminated.
It order to make it correct you should use:
只需使用 strlcpy() 而不是 strncpy()。
您必须检查它是否适用于所有平台。
早期版本的 Linux 可能没有它。
Just use strlcpy() instead of strncpy().
You'll have to check if it's available on all platforms.
Early versions of linux probably don't have it.
使用 strlcpy 的方式与 strncpy 相同。 不需要在第三个参数中执行 size-1
即:
strncpy(call, info.called, sizeof(call)-1);
或者
strlcpy(call, info.called, sizeof(call));
Use strlcpy in same way as strncpy. no need to do size-1 in 3rd parameter
i.e:
strncpy(call, info.called, sizeof(call)-1);
or
strlcpy(call, info.called, sizeof(call));