【问题标题】:strncpy() alternative - what advatages to each version?strncpy() 替代方案 - 每个版本有什么优势?
【发布时间】:2016-04-27 19:36:54
【问题描述】:

我正在考虑使用终止 '\0' 来替代 strncpy 以供我自己在头文件中使用,并且想知道以下哪种方法会更好。

int copystring(char *dest,char *source,int elements)
{
    int run;
    for(run=0;run<elements-1;run++)//last reserved for'\0'
    {
       dest[run]=source [run];
       if (dest[run]=='\0')
       {
           break;
       }

    }
    dest[elements-1]='\0';//could make conditional but not neccesary.
    return 0;
}

int copystring(char *dest,char *source,int elements)
 {
        strncpy(dest,source,elements-1);
        dest[elements-1]='\0';
        return 0;
  }

对我来说明显的区别是我在版本一中调用了一个更少的函数,但我想知道版本二是否有任何优势,因为我不知道 strncpy() 的内部工作原理

顺便说一句,为什么 strncpy() 将 size_t 作为最后的参数?如果它是用于传递 sizeof 值,这仅在非常有限的情况下有用,那么 int 不是也可以吗?

【问题讨论】:

  • strcopy 还没有提供什么?此外,为什么您需要知道以 null 结尾的 char *source 的长度才能复制它?
  • 它对 dest 有缓冲区溢出保护。即我将使用“元素”来传递最大目标长度。
  • 顺便说一句:dest[run+1]='\0'; -->> dest[run]='\0';(循环后运行已经递增)
  • @KeithThompson 啊,绝对是,我打字太快了。 s/copy/cpy/g请。 #define strcopy strcpy#define strncopy strncpy
  • @Orangesandlemons 要明确:copystring(dest, source, 0) 调用 strncpy(dest,source,0-1);strncpy(dest,source,some_very_large_number); 而不是 strncpy(dest,source, -1);

标签: c strncpy


【解决方案1】:

strncpy() 的最简单替换(如果您觉得需要)可能是这样的:

dest[0] = '\0';
strncat(dest, source, size);

strncat()strncpy() 不同,它保证目标正确地以空值结尾,并且在目标大于源时不会复制额外的空字节。

但请确保这种行为确实是您想要的。如果你使用strcpy() 并且目标数组不够大,你会得到未定义的行为。使用strncpystrncat,您将获得明确的行为:值被悄悄截断。如果这就是你想要的,那很好——但它很少是。更常见的是,截断数据只会给你带来坏数据,你应该检测到它并将其作为错误处理,而不是 Procusteanly 丢弃任何不适合的数据。 (将"rm -rf $HOME/unimportant_directory" 截断为"rm -rf $HOME",然后将其传递给system()。)

顺便说一句,为什么strncpy()size_t 作为最后的参数?如果 它用于传递sizeof 值,仅在非常有用的情况下 在有限的情况下,int 不也可以吗?

size_t 更有意义,因为它是用于表示大小和长度的类型。使用int 需要定义(或未定义)负参数的行为,并且可能会限制您可以处理的字符串的大小(例如,int 是 16 位,size_t 是 32 位)。您始终可以传递int 值,它会隐式转换为size_t

另一个选项是非标准的strlcpy() 函数。它并非在所有系统上都可用,但您应该能够安装它(例如,使用 Debian/Ubuntu/... 系统的 libbsd-dev 软件包)或从源代码构建它。

顺便说一下,这是我对strncpy()的话题的吐槽:
http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html

【讨论】:

  • 我的计划是继续读取字符串直到到达末尾(但不是进入数组),然后将该数字作为函数返回返回,允许根据需要进行自定义错误处理。当然,如果我需要所有的字符,我将不得不动态分配
  • 注意:重要的是size 不超过dest 指向的空间大小。 2) 顺便说一句:OP 的 2 个选项之间的不错选择:两者都不是
  • 这样做的一个缺点是它需要使用 '\0' 初始化 dest [0],而理想情况下我会尽可能少地编写代码。在数组衰减为指针等情况下,我仍在尝试找出一种无需告诉我的函数目标数组的大小的方法。
  • @Orangesandlemons:你不能避免告诉你的函数目标数组的大小,除非你愿意允许缓冲区溢出。
  • @Keith Thompson 我知道,但如果数组没有衰减,我可以在内部告诉它,而不是将它作为参数传递,从而制作一个更“干净”的函数。跨度>
猜你喜欢
  • 2017-06-11
  • 1970-01-01
  • 2013-12-11
  • 2016-11-07
  • 1970-01-01
  • 2010-10-29
  • 2012-04-08
  • 2020-03-09
  • 1970-01-01
相关资源
最近更新 更多