2013-02-15 155 views
3

使用wcscpy_s和使用wcsncpy有什么实际区别吗?唯一的区别似乎是参数和返回值的顺序:wcsncpy和wcscpy_s有何区别?

errno_t wcscpy_s(wchar_t *strDestination, 
       size_t numberOfElements, 
       const wchar_t *strSource); 

wchar_t *wcsncpy(wchar_t *strDest, 
       const wchar_t *strSource, 
       size_t count); 

如果没有实际的区别,为什么微软需要添加wcscpy_s到Visual Studio中,当wcsncpy都是现成的和标准的功能?

从Visual Studio移植到gcc时,将wcscpy_s更换为wcsncpy可以吗?

回答

9

这两个函数没有相同的行为。

the MSDN documentation of wcscpy_s

成功执行后,目标字符串将永远是空终止。

wcsncpy说明书(C11 7.29.4.2.2/1-3):

#include <wchar.h> 
wchar_t *wcsncpy(wchar_t * restrict s1, 
    const wchar_t * restrict s2, 
    size_t n); 

wcsncpy功能拷贝不超过n宽字符(那些遵循空 宽字符不复制)从s2指向的数组到 s1指向的数组。

如果数组指向s2是一个宽字符串短于n宽字符,空宽字符被附加到阵列中的拷贝指向s1,直到在所有n宽字符已被写入

和脚注(#346):

因此,如果没有空宽字符在所述阵列的所述第一n宽字符由s2指出,所述结果不会以null结尾。

注意strncpywcsncpy不是专为null结尾的字符串使用。它们设计用于空填充,固定宽度的字符串。

+0

我还会注意到Visual Studio包含了CRT的源代码。如果您对某个特定功能的实现方式感到好奇(或者两个功能之间有什么不同),您可以查看一下。 – 2013-02-15 10:15:31

0

附加_s的函数是更安全的函数。通常,不包含尾部_s的函数将被例如VS2012标记为“不赞成”。你会得到一个警告。有关其他信息:MSDN有大量的相关信息。

+0

谢谢,但是当它们都接受目标缓冲区的容量时,'wcscpy_s'比'wcsncpy'更安全吗? – sashoalm 2013-02-15 10:04:08

+0

我相信这不是关于用户/开发者的安全性,而是关于C-Runtime的安全性。 – 2013-02-15 10:05:09

3

另一个区别(只花了几个小时的时间盯着代码,想知道发生了什么)是,wcscpy_s函数默认情况下会在应用程序溢出缓冲区时终止应用程序。

我预计它会像strncpy变体之一一样。事实并非如此!

用_set_invalid_parameter_handler函数显然可以改变这种行为。