On my new job we do not use MFC - but luckily std lib and C++11 - so I've come up to the same question as c00000fd. Thanks to BitTickler's answer I came up with the idea of using the string's internal buffer for Win32-APIs via the &s[0]
resp. &s.front()
catch.
Using a Win32-API function that shrinks the internal string buffer
Assuming that you have a string which shall become shortened by a Win32-API function - e.g. ::PathRemoveFileSpec(path)
- you may follow this approach:
std::string path( R("?(C:\TESTING\toBeCutOff)?") );
::PathRemoveFileSpec( &path.front() ); // Using the Win32-API
// and the the string's internal buffer
path.resize( strlen( path.data() ) ); // adjust the string's length
// to the first \0 character
path.shrink_to_fit(); // optional to adjust the string's
// capacity - useful if you
// do not plan to modify the string again
Unicode Version:
std::wstring path( LR("?(C:\TESTING\toBeCutOff)?") );
::PathRemoveFileSpec( &path.front() ); // Using the Win32-API
// and the the string's internal buffer
path.resize( wcslen( path.data() ) ); // adjust the string's length
// to the first \0 character
path.shrink_to_fit(); // optional to adjust the string's
// capacity - useful if you
// do not plan to modify the string again
Using a Win32-API function that extends the internal string buffer
Assuming that you have a string which shall become extended or filled by a Win32-API function - e.g. ::GetModuleFileName(NULL, path, cPath)
to retrieve your executable's path - you may follow this approach:
std::string path;
path.resize(MAX_PATH); // adjust the internal buffer's size
// to the expected (max) size of the
// output-buffer of the Win32-API function
::GetModuleFileName( NULL, &path.front(), static_cast<DWORD>( path.size() ) );
// Using the Win32-API
// and the the string's internal buffer
path.resize( strlen( path.data() ) ); // adjust the string's length
// to the first \0 character
path.shrink_to_fit(); // optional to adjust the string's
// capacity - useful if you
// do not plan to modify the string again
Unicode Version:
std::wstring path;
path.resize(MAX_PATH); // adjust the internal buffer's size
// to the expected (max) size of the
// output-buffer of the Win32-API function
::GetModuleFileName( NULL, &path.front(), static_cast<DWORD>( path.size() ) );
// Using the Win32-API
// and the the string's internal buffer
path.resize( wcslen( path.data() ) ); // adjust the string's length
// to the first \0 character
path.shrink_to_fit(); // optional to adjust the string's
// capacity - useful if you
// do not plan to modify the string again
When you finally shrink-to-fit the string then you need just one more line of code when extending the string's internal buffer compared with the MFC alternative, when shrinking the string it has nearly the same overhead.
The advantage of the std::string
approach in contrast to the CString
approach is that you do not have to declare an additional C-String pointer variable, you just work with the official std::string
methods and with one strlen
/wcslen
function.
My approach shown above only works for the shrinking variant when the resulting Win32-API buffer is null-terminated, but for that very special case in which the Win32-API returns an unterminated string, then - similar to the CString::ReleaseBuffer
method - you must explicitly know and specify the new string/buffer length by path.resize( newLength )
- just like path.ReleaseBuffer( newLength )
for the CString
alternative.