我在代码中使用了字符串安全函数(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吗?
答案 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更多的东西。)