如何从 std::string 获取可写的 C 缓冲区? [英] How to get a writable C buffer from std::string?

查看:41
本文介绍了如何从 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.

这篇关于如何从 std::string 获取可写的 C 缓冲区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆