StringCch *函数和Cstring

时间:2019-07-17 22:26:35

标签: c++ mfc c-strings strsafe

我在代码中使用了字符串安全函数(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吗?

1 个答案:

答案 0 :(得分: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的赋值运算符一起使用。 (假设数据以null终止并且我们不会进入char vs wchar领域,在这种情况下,您可能仍然需要比StringCchCopy更多的东西。)