I am using string safe functions (StringCch*) in my code. However, some functions I want to convert the variables from WCHAR * to CString. This code is failing on the StringCchCopy functions:
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());
Easy answer I'm sure, but I'm a bit stumped!
And GetAllocLength() is returning 71. Shouldn't it return 64?
StringCchCopy(sFile, 64, L"ini");I'm surprised this even compiles. The first parameter of StringCchCopy is supposed to be a non-const pointer to the destination buffer. CString should not implicitly convert to such a thing (at least not as far as I'm aware from the last time I seriously used CString). So whatever this is doing, it's probably not what you want.If you're going to do things this way, it's probably easier to use the overload of GetBuffer which takes a length combined with ReleaseBuffer.
GetBuffer(X)makes sure the CString has an internal buffer with enough space to fit X -1 characters and a null terminator, and returns a non-const pointer to that buffer.Then
ReleaseBufferwill cause the CString to look at whatever has been written into that buffer, find the null terminator, and figure out how long of a string it now manages. (If you want to do stuff without null terminators then go read the documentation in detail for how use it correctly for that.)So something like
After that
sFileshould be valid and contain the data. And GetLength will reflect that.I wouldn't worry about GetAllocLength. Though MSDN doesn't seem to explain much of anything about it, I wouldn't be surprised if it returns the entire length of an internal buffer - which CString might have decided to oversize of some particular reason. Unless you're really trying to micro-optimize something (in which case why are you even using CString), you should never need to worry about such things.
However there's kinda no point to all this though, since you could just do
sFile = L"ini";That's simpler and avoids any potential off-by-one errors from making mistakes with buffer sizes.Even if this is a simplified example, if you code has a string (pointer to a char array) then you can still just use that directly with the assignment operator of CString. (Assuming the data is null terminated and we're not getting into char vs wchar territory, in which case you may need more than StringCchCopy anyway.)