C语言 在我的情况下 strncpy 或 strlcpy

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6987217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:19:50  来源:igfitidea点击:

strncpy or strlcpy in my case

ccopyc-stringsstrncpy

提问by hari

what should I use when I want to copy src_strto dst_arrand why?

当我想复制src_str到时应该使用什么dst_arr,为什么?

char dst_arr[10];
char *src_str = "hello";

PS: my head is spinning faster than the disk of my computer after reading a lot of things on how goodor badis strncpyand strlcpy.

PS:我的头正在读的东西很多关于如何纺纱后比我的电脑硬盘快strncpystrlcpy

Note: I know strlcpyis not available everywhere. That is not the concern here.

注意:我知道strlcpy并非随处可用。这不是这里的问题。

回答by AnT

strncpyis neverthe right answer when your destination string is zero-terminated. strncpyis a function intended to be used with non-terminated fixed-widthstrings. More precisely, its purpose is to convert a zero-terminated string to a non-terminated fixed-width string (by copying). In other words, strncpyis not meaningfully applicable here.

strncpy永远当你的目标字符串零终止正确的答案。strncpy是一个旨在与非终止固定宽度字符串一起使用的函数。更准确地说,它的目的是将零终止字符串转换为非终止固定宽度字符串(通过复制)。换句话说,strncpy在这里没有意义地适用。

The real choice you have here is between strlcpyand plain strcpy.

您在这里的真正选择是介于strlcpy和之间strcpy

When you want to perform "safe" (i.e. potentially truncated) copying to dst_arr, the proper function to use is strlcpy.

当您想要执行“安全”(即可能被截断)复制到 时dst_arr,要使用的正确函数是strlcpy.

As for dst_ptr... There's no such thing as "copy to dst_ptr". You can copy to memorypointed by dst_ptr, but first you have to make sure it points somewhere and allocate that memory. There are many different ways to do it.

至于dst_ptr......没有“复制到dst_ptr”这样的东西。您可以复制到由 指向的内存dst_ptr,但首先您必须确保它指向某个地方并分配该内存。有许多不同的方法可以做到这一点。

For example, you can just make dst_ptrto point to dst_arr, in which case the answer is the same as in the previous case - strlcpy.

例如,您可以直接dst_ptr指向dst_arr,在这种情况下,答案与前一种情况相同 - strlcpy

Or you can allocate the memory using malloc. If the amount of memory you allocated is guaranteed to be enough for the string (i.e. at least strlen(src_str) + 1bytes is allocated), then you can use the plain strcpyor even memcpyto copy the string. There's no need and no reason to use strlcpyin this case , although some people might prefer using it, since it somehow gives them the feeling of extra safety.

或者您可以使用malloc. 如果您分配的内存量保证足够用于字符串(即至少strlen(src_str) + 1分配了字节),那么您可以使用普通strcpy甚至memcpy复制字符串。strlcpy在这种情况下没有必要也没有理由使用,尽管有些人可能更喜欢使用它,因为它以某种方式给了他们额外的安全感。

If you intentionally allocate less memory (i.e. you want your string to get truncated), then strlcpybecomes the right function to use.

如果您有意分配较少的内存(即您希望您的字符串被截断),则strlcpy成为要使用的正确函数。

回答by Martin Beckett

strlcpy()is safer than strncpy()so you might as well use it.
Systems that don't have it will often have a s_strncpy()that does the same thing.

strlcpy()strncpy()这样更安全,您不妨使用它。
没有它的系统通常会有一个s_strncpy()做同样事情的系统。

Note: you can't copy anything to dst_ptruntil it points to something

注意:你不能复制任何东西,dst_ptr直到它指向某个东西

回答by jfg956

I did not know of strlcpy. I just found herethat:

我不知道strlcpy。我刚刚在这里发现:

The strlcpy() and strlcat() functions copy and concatenate strings respectively. They are designed to be safer, more consistent, and less error prone replacements for strncpy(3) and strncat(3).

strlcpy() 和 strlcat() 函数分别复制和连接字符串。它们被设计为更安全、更一致且不易出错的 strncpy(3) 和 strncat(3) 替代品。

So strlcpy seams safer.

所以 strlcpy 接缝更安全。

Edit: A full discussion is available here.

编辑这里有完整的讨论。

Edit2:

编辑2

I realize that what I wrote above does not answer the "in your case" part of your question. If you understandthe limitations of strncpy, I guess you can use it and write good code around it to avoid its pitfalls; but if your are not sure about your understanding of its limits, use strlcpy.

我意识到我上面写的内容并没有回答你问题的“在你的情况下”的部分。如果您了解strncpy 的局限性,我想您可以使用它并围绕它编写好的代码以避免其陷阱;但如果您不确定自己对其限制的理解,请使用 strlcpy。

My understanding of the limitations of strncpy and strlcpy is that you can do something very bad with strncpy (buffer overflow), and the worst you can do with strlcpy is to loose one char in the process.

我对 strncpy 和 strlcpy 的限制的理解是,您可以使用 strncpy(缓冲区溢出)做一些非常糟糕的事情,而使用 strlcpy 可以做的最糟糕的事情是在此过程中丢失一个字符。

回答by rurban

You should always the standard function, which in this case is the C11 strcpy_s()function. Not strncpy(), as this is unsafe not guaranteeing zero termination. And not the OpenBSD-only strlcpy(), as it is also unsafe, and OpenBSD always comes up with it's own inventions, which usually don't make it into any standard.

您应该始终使用标准函数,在本例中为 C11strcpy_s()函数。不strncpy(),因为这是不安全的,不能保证零终止。而不是 OpenBSD-only strlcpy(),因为它也不安全,而且 OpenBSD 总是提出自己的发明,通常不会将其纳入任何标准。

See http://en.cppreference.com/w/c/string/byte/strcpy

请参阅 http://en.cppreference.com/w/c/string/byte/strcpy

The function strcpy_s is similar to the BSD function strlcpy, except that strlcpy truncates the source string to fit in the destination (which is a security risk)

函数 strcpy_s 与 BSD 函数 strlcpy 类似,不同之处在于 strlcpy 截断源字符串以适应目标(这是一个安全风险)

  • strlcpy does not perform all the runtime checks that strcpy_s does
  • strlcpy does not make failures obvious by setting the destination to a null string or calling a handler if the call fails.
  • Although strcpy_s prohibits truncation due to potential security risks, it's possible to truncate a string using bounds-checked strncpy_s instead.
  • strlcpy 不执行 strcpy_s 所做的所有运行时检查
  • strlcpy 不会通过将目标设置为空字符串或在调用失败时调用处理程序来使失败变得明显。
  • 尽管 strcpy_s 由于​​潜在的安全风险而禁止截断,但可以使用边界检查的 strncpy_s 来截断字符串。

If your C library doesn't have strcpy_s, use the safec lib. https://rurban.github.io/safeclib/doc/safec-3.1/df/d8e/strcpy__s_8c.html

如果您的 C 库没有strcpy_s,请使用 safec 库。 https://rurban.github.io/safeclib/doc/safec-3.1/df/d8e/strcpy__s_8c.html

回答by John Humphreys - w00te

First of all, your dst_ptr has no space allocated and you haven't set it to point at the others, so assigning anything to that would probably cause a segmentation fault.

首先,您的 dst_ptr 没有分配空间,并且您没有将其设置为指向其他空间,因此分配任何内容可能会导致分段错误。

Strncpy should work perfectly fine - just do:

Strncpy 应该可以正常工作 - 只需执行以下操作:

strncpy(dst_arr, src_str, sizeof(dst_arr));

and you know you wont overflow dst_arr. If you use a bigger src_str you might have to put your own null-terminator at the end of dst_arr, but in this case your source is < your dest, so it will be padded with nulls anyway.

你知道你不会溢出dst_arr。如果您使用更大的 src_str,您可能必须在 dst_arr 的末尾放置您自己的空终止符,但在这种情况下,您的源是 < 您的目标,因此无论如何它将用空值填充。

This works everywhere and its safe, so I wouldn't look at anything else unless its intellectual curiousity.

这在任何地方都有效且安全,所以除非它的智力好奇,否则我不会看任何其他东西。

Also note that it would be good to use a non-magic number for the 10 so you know the size of that matches the size of the strncpy :)

另请注意,最好对 10 使用非幻数,这样您就知道它的大小与 strncpy 的大小相匹配:)

回答by user411313

you should not use strncpy and not strlcpy for this. Better you use

你不应该为此使用 strncpy 和 strlcpy 。更好地使用

*dst_arr=0; strncat(dst_arr,src_arr,(sizeof dst_arr)-1);

or without an initialization

或没有初始化

sprintf(dst_arr,"%.*s",(sizeof dst_arr)-1,src_arr);

dst_arr here must be an array NOT a pointer.

dst_arr 这里必须是一个数组而不是一个指针。