0

我在我的代码中使用字符串安全函数 (StringCch*)。但是,有些函数我想将变量从 转换WCHAR *CString. 此代码在 StringCchCopy 函数上失败:

CString sFile;
sFile.Preallocate(64);
StringCchCopy(sFile, 64, L"ini");

DWORD rv = sFile.GetAllocLength();
rv = sFile.GetLength();

TCHAR sVal[64] = {0};
StringCchCopy(sVal, 64, sFile.GetBuffer());

简单的答案我敢肯定,但我有点难过!

并且GetAllocLength()返回 71。它不应该返回 64 吗?

4

1 回答 1

3

StringCchCopy(sFile, 64, L"ini");我很惊讶这甚至可以编译。StringCchCopy 的第一个参数应该是指向目标缓冲区的非常量指针。CString 不应该隐式转换为这样的东西(至少据我上次认真使用 CString 时所知道的)。所以无论这在做什么,它可能不是你想要的。

如果您打算以这种方式做事,使用GetBuffer的重载可能更容易,它需要一个长度与ReleaseBuffer相结合。

GetBuffer(X)确保 CString 有一个内部缓冲区,该缓冲区有足够的空间来容纳 X -1 个字符和一个空终止符,并返回一个指向该缓冲区的非常量指针。

然后ReleaseBuffer将导致 CString 查看已写入该缓冲区的任何内容,找到空终止符,并计算出它现在管理的字符串的长度。(如果您想在没有空终止符的情况下做一些事情,那么请详细阅读文档以了解如何正确使用它。)

所以像

CString sFile;
StringCchCopy(sFile.GetBuffer(63), 64, L"ini");
sFile.ReleaseBuffer();

之后sFile应该是有效的并包含数据。GetLength 将反映这一点。

我不会担心 GetAllocLength。尽管 MSDN 似乎没有解释太多,但如果它返回内部缓冲区的整个长度,我不会感到惊讶——CString 可能出于某种特殊原因决定过大。除非您真的在尝试对某些东西进行微优化(在这种情况下,您为什么还要使用 CString),否则您永远不需要担心这些事情。


但是,这一切都毫无意义,因为您可以这样做sFile = L"ini";更简单,并避免因缓冲区大小出错而导致的任何潜在错误。

即使这是一个简化的示例,如果您的代码有一个字符串(指向 char 数组的指针),那么您仍然可以直接将它与 CString 的赋值运算符一起使用。(假设数据以空值终止,并且我们没有进入 char 与 wchar 的领域,在这种情况下,无论如何您可能需要的不仅仅是 StringCchCopy。)

于 2019-07-18T01:06:46.657 回答