如何从 std::string 获取可写的 C 缓冲区?
我正在尝试将我的代码从使用 MFC 的 CString
移植到 Microsoft Windows 平台的 std::string
.我对某事感到好奇.在下面的例子中说:
I'm trying to port my code from using MFC's CString
to std::string
for Microsoft Windows platform. And I'm curious about something. Say in the following example:
CString MakeLowerString(LPCTSTR pStr)
{
CString strLower = pStr ? pStr : L"";
CharLower(strLower.GetBuffer()); //Use WinAPI
strLower.ReleaseBuffer();
return strLower;
}
我使用 strLower.GetBuffer() 获取可写缓冲区传递给 CharLower一个> API.但我在 std::string
中没有看到类似的方法.
I use strLower.GetBuffer() to obtain a writable buffer to be passed to the CharLower API. But I don't see a similar method in std::string
.
我错过了什么吗?如果是这样,您将如何使用 std::string
覆盖上述方法?
Am I missing something? And if so, how would you overwrite the method above using std::string
?
推荐答案
在我的新工作中,我们不使用 MFC - 但幸运的是 std lib 和 C++11 - 所以我提出了与 c00000fd 相同的问题.感谢 BitTickler 的回答,我想出了通过 &s[0]
分别将字符串的内部缓冲区用于 Win32-API 的想法.&s.front()
捕捉.
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.
假设您有一个字符串,该字符串将被 Win32-API 函数缩短 - 例如::PathRemoveFileSpec(path)
- 你可以采用这种方法:
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 oBeCutOff)?") );
::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 character
path.shrink_to_fit(); // optional to adjust the string's
// capacity - useful if you
// do not plan to modify the string again
Unicode 版本:
Unicode Version:
std::wstring path( LR("?(C:TESTING oBeCutOff)?") );
::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 character
path.shrink_to_fit(); // optional to adjust the string's
// capacity - useful if you
// do not plan to modify the string again
使用扩展内部字符串缓冲区的 Win32-API 函数
假设您有一个字符串,该字符串将被 Win32-API 函数扩展或填充 - 例如::GetModuleFileName(NULL, path, cPath)
来检索可执行文件的路径 - 您可以采用这种方法:
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 character
path.shrink_to_fit(); // optional to adjust the string's
// capacity - useful if you
// do not plan to modify the string again
Unicode 版本:
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 character
path.shrink_to_fit(); // optional to adjust the string's
// capacity - useful if you
// do not plan to modify the string again
当您最终缩小以适应字符串时,与 MFC 替代方案相比,在扩展字符串的内部缓冲区时,您只需要多行代码,在缩小字符串时,它的开销几乎相同.
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.
std::string
方法与 CString
方法相比的优势在于您不必声明额外的 C-String 指针变量,您只需使用官方的 std::string
方法和一个 strlen
/wcslen
函数.我上面显示的方法仅适用于结果 Win32-API 缓冲区为空终止时的缩小变体,但对于 Win32-API 返回未终止字符串的非常特殊的情况,然后 - 类似于 CString::ReleaseBuffer
方法 - 您必须通过 path.resize( newLength )
明确知道并指定新的字符串/缓冲区长度 - 就像 path.ReleaseBuffer( newLength )
一样CString
替代方案.
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.
相关文章