我正在考虑通过终止' \ 0'来制定一个强大的替代方案。我自己在头文件中使用,并想知道以下哪种方法会更好。
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;
}
OR
int copystring(char *dest,char *source,int elements)
{
strncpy(dest,source,elements-1);
dest[elements-1]='\0';
return 0;
}
对我来说明显不同的是,我在版本1中调用的功能较少,但我想知道版本2是否有任何优势,因为我不知道strncpy()的内部工作原理< / p>
顺便说一下,为什么strncpy()将size_t作为最终参数?如果它传递sizeof值,这只会在非常有限的情况下有用,那么int也不会这样做吗?
答案 0 :(得分:2)
strncpy()
的最简单替换(如果你认为你需要一个)可能是这样的:
dest[0] = '\0';
strncat(dest, source, size);
与strncat()
不同, strncpy()
保证目标正确地以空值终止,并且当目标大于源时,不会复制额外的空字节。
但请确保此行为确实是您想要的。如果使用strcpy()
并且目标数组不够大,则会得到未定义的行为。使用strncpy
或strncat
,您将获得已定义的行为:该值被静默截断。如果这就是你想要的,那很棒 - 但它很少。更常见的是,截断数据只会为您提供错误的数据,您应该检测它并将其作为错误处理,而不是逐步丢弃任何不合适的数据。 (在将"rm -rf $HOME/unimportant_directory"
传递给"rm -rf $HOME"
之前,将system()
截断为strncpy()
。
顺便说一下,为什么
size_t
将sizeof
作为最终论证?如果 它传递int
值,这只会非常有用 有限的情况,size_t
不会做同样的事情吗?
int
更有意义,因为它是用于表示大小和长度的类型。使用int
需要定义(或保留undefined)负参数的行为,并且可能会限制您可以处理的字符串的大小(例如,size_t
是16位和int
是32位)。您始终可以传递size_t
值,并将其隐式转换为libbsd-dev
。
另一个选项是非标准strlcpy()
功能。它并非在所有系统上都可用,但您应该能够安装它(例如,使用Debian / Ubuntu / ...系统的strncpy()
包)或从源代码构建它。
顺便说一句,这是我对<a href="http://www.w3schools.com"><img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;"></a>
主题的咆哮:
http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html