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

查看:405
本文介绍了如何从std :: string获取可写的C缓冲区?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于Microsoft Windows平台,我试图将我的代码从使用MFC的CString移植到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] resp将字符串的内部缓冲区用于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\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版本:

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

使用一个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 \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版本:

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

当最终收缩以适合字符串时,与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.

CString方法相比,std::string方法的优点是您不必声明其他C-String指针变量,只需使用官方的std::string方法和一个/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天全站免登陆