将 strcpy_s 用于 TCHAR 指针(Microsoft 特定)

Posted

技术标签:

【中文标题】将 strcpy_s 用于 TCHAR 指针(Microsoft 特定)【英文标题】:using strcpy_s for TCHAR pointer (Microsoft Specific) 【发布时间】:2010-06-01 02:04:21 【问题描述】:

我想知道哪种方法是正确的?

_tcscpy(tchar_pointer, _tcslen(tchar_pointer), _T("Hello World"));

_tcscpy(tchar_pointer, _tcsclen(tchar_pointer), _T("Hello World"));

_tcscpy(tchar_pointer, ???, _T("Hello World"));

【问题讨论】:

【参考方案1】:

假设您使用的是_tcscpy_s 而不是_tcscpy,那么第二个参数应该是数组的实际大小,而不是当前包含的字符串的长度。例如:

TCHAR dest[20];
_tcscpy_s(dest, _countof(dest), _T("Hello"));

您甚至可以使用不需要 size 参数的 2 参数版本:

_tcscpy_s(dest, _T("Hello"));

如果tchar_pointer 实际上是一个指针而不是一个数组(正如其名称所暗示的那样),则在确定其实际容量时需要非常小心。需要更多的上下文来建议正确的方法,但是使用包含的字符串的长度来计算缓冲区的大小几乎肯定是错误的方法。

【讨论】:

以上 2 建议不起作用,因为 tchar 指针来自外部,我这边不知道指针引用的缓冲区有多大。 那么你不能使用安全的_s 函数,因为这些函数的全部意义在于你提供了缓冲区大小。【参考方案2】:

tchar 指针来自外部,我这边不知道指针引用的缓冲区有多大

如果是这样,那么这些都不是你想要的。

所有“安全”函数的工作方式是告诉它们目标缓冲区有多大。

你不知道吗?你不能使用这些功能。

int buffer_size = _tcslen(xxx) * sizeof(TCHAR)

行不通。它将保证复制的字符串不比缓冲区中已有的字符串长。如果缓冲区没有被初始化,就会失败;如果缓冲区以'\0' 开头,则不会复制任何内容;等等。

【讨论】:

【参考方案3】:

bara 的答案对您来说非常重要,因为正确答案与您列出的所有想法都不同。但是bara没有向你解释_tcslen和_tcsclen的区别,所以我会这样做。

在 Unicode 编译中,_tcslen 和 _tcsclen 都会计算字符串当前值中的 TCHAR 数。每个 TCHAR 是一个 wchar_t。

在多字节编译中,_tcslen 将计算字符串当前值中的 TCHAR 数。每个 TCHAR 是一个字符。但是 _tcsclen 会计算字符串当前值中多字节字符的数量。每个多字节字符是一个或多个 TCHAR,每个多字节字符是一个或多个字符。不同的多字节字符可以有不同的长度,具体取决于代码页和各个字符。

【讨论】:

那么,我可以将 int buffer_size = _tcslen(xxx) * sizeof(TCHAR) 用于 unicode 和多字节环境的第二个参数吗? 否,但您可以将 int current_occupied_size = _tcslen(xxx) * sizeof(TCHAR) 用于 unicode 和多字节环境的第二个参数。如果缓冲区大小大于当前占用的大小,那么您正在浪费无法测量的空间。如果缓冲区大小小于当前占用的大小,则表示缓冲区溢出,您正在帮助传播病毒。你最好找出真正的缓冲区大小。【参考方案4】:

如果tchar_pointer 是一个指针(而不是数组),您应该知道自己指向的缓冲区有多大。如果您不知道,则无法从原始指针中找到,strcpy_s 无济于事。

【讨论】:

以上是关于将 strcpy_s 用于 TCHAR 指针(Microsoft 特定)的主要内容,如果未能解决你的问题,请参考以下文章

VS2013 C++中的strcpy用不了,说换成strcpy_s,还是出现错误了。

c++如何拼接两个tchar字符串?

可以将指针声明为 void 存储椅子吗?

如何将当前的 strcpy 转换为 strcpy_s?

SendInput始终将鼠标指针移动到左上角

C语言 strcpy_s 函数