strncpy 并使用 sizeof 复制最大字符数

发布于 2024-07-27 17:39:39 字数 476 浏览 6 评论 0原文

我使用下面的代码,

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

海之角 2024-08-03 17:39:39

如果 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

strncpy will not null-terminate the destination if it truncates the string. If you must use strncpy, you need to ensure that the result is terminated, something like:

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

BSD's strlcpy(), among others, is generally considered superior:

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

并安 2024-08-03 17:39:39

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

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

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

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

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:

char buffer[bufferSize + 1];
strncpy( buffer, source, bufferSize );
*(buffer + bufferSize ) = 0;
如果没有 2024-08-03 17:39:39

您的想法:

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

行不通,因为您将在非终止字符串上调用 strlen()

Your idea:

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

would not work, as you would be calling strlen() on a non-terminated string

旧话新听 2024-08-03 17:39:39

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

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

实现此目的的一个好方法是为 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:

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

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.

绮烟 2024-08-03 17:39:39

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

不,strncpy 不承诺目标字符串将以 null 结尾。

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

But I am now wondering if it will null terminate the destination.

No, strncpy does not promise that target string would be null terminated.

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

It order to make it correct you should use:

strncpy(traget,string,sizeof(target)-1);
target[sizeof(target)-1]=0
知足的幸福 2024-08-03 17:39:39

只需使用 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.

梦言归人 2024-08-03 17:39:39

使用 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));

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文