首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确使用strncpy?

如何正确使用strncpy?
EN

Stack Overflow用户
提问于 2018-09-06 15:11:03
回答 3查看 9.7K关注 0票数 3

我知道strncpystrcpy的一个更安全的版本,正如here所说的那样。

但是,当我想从src复制到dst并且dst不是一个干净的缓冲区时,我会得到不想要的结果,这是strcpy可以避免的。

代码语言:javascript
复制
char *p = "123";
char a[10] = "aaaaaa";

strncpy(a,p,strlen(p));
printf("%s\n", a);   // 123aaa

strcpy(a,p);
printf("%s\n", a);   // 123 <- desired output, as the trailing a's are garbage

在我的实际案例中,我知道strlen(src) < sizeof(dst) (至少,如果不是这样的话,程序会很快崩溃),所以我可以安全地使用strcpy

但是,如果strncpy是我应该使用的,那么必须在dst[strlen(src)] = '\0'之后添加以避免垃圾(或者更好的做法是预先插入缓冲区)?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-09-06 15:14:46

strncpy的第三个参数表示目标缓冲区的大小。当它填充时,它不会按设计添加空终止字符。

如果您有足够的空间作为终止符,并且您坚持使用strncpy,那么只需传递strlen(p) + 1,这样它就不会假定它耗尽了目标缓冲区。

就像很多人已经注意到的那样。这种对strncpy的使用违背了目的,而且实际上也不比对strcpy的简单调用更好。strncpy的唯一实际用途是,如果您想要覆盖字符串的一部分(这是您偶然发现的用例)。虽然这也是值得怀疑的用途..。

票数 11
EN

Stack Overflow用户

发布于 2018-09-06 16:40:13

如何正确使用strncpy?

当代码需要将字符串复制到目标,并允许结果终止或完全复制时,请使用sizeof destination作为size参数:

代码语言:javascript
复制
char a[10];
// strncpy(a,p,strlen(p));
strncpy(a, p, sizeof a);

// printf("%s\n", a);
printf("%.*s\n", (int) sizeof a, a);

当代码希望通过strncpy()复制字符串并检测内存不足问题或需要空字符'\0'填充时,也可以使用sizeof destination

代码语言:javascript
复制
char a[10];
strncpy(a, p, sizeof a);
if (a[sizeof a - 1] != '\0') {
  // insufficient memory
  // Maybe set last last character to the null character 
  a[sizeof a - 1] == '\0';
  // or other more robust handling
  return ERROR_INSUFFICIENT_MEMORY;
}

否则不要使用strncpy()

当不需要空字符strncpy()填充时,有更有效的方法来检测内存不足。strncpy()零填充未复制缓冲区的其余部分(如果有的话)。以下消耗大量的时间零填充,只是为了提供一个不足的检查。

代码语言:javascript
复制
char a[1000];
strncpy(a, "abc", sizeof a);
if (a[sizeof a - 1] != '\0') {
  ....

更好的替代方案采用strlen(), strlcpy(), memcpy()@Deduplicator

另见strncpy or strlcpy in my case

对于标准的C库一行,代码可以使用snprintf()和一行错误检测。一个好的编译器应该分析snprintf(a, sizeof a, "%s", p)并发出高效的代码。

代码语言:javascript
复制
// Copy with no overflow.
// 'a' is always null character terminated.
int len = snprintf(a, sizeof a, "%s", p);
if (len < 0 || (unsigned) len >= sizeof a) Report_truncated_copy();
票数 7
EN

Stack Overflow用户

发布于 2018-09-06 15:58:32

strncpy()实际上不是一个字符串函数;相反,它处理非零字符的零填充序列,这些字符加在一起有一个已知的固定长度。例如,它是填充数据结构的正确工具,这些数据结构随后被发送到其他程序、外部程序或持久化程序,以避免数据泄漏。

试图在其非常专门的利基之外使用它,会导致可怕的扭曲和低效的代码。

有更合适的方法来解决这个问题,比如strlcpy()和/或手动使用strlen()memcpy()

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52207214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档