std::string::resize() 对缓冲区一些用处
如果需要一个缓冲区来暂存字符串会先定义一个char*的数组来实现
存完后又给string赋值,感觉有点麻烦,寻思有什么方法可以更优雅点
比如如下代码
1 void CVTString::StrToWStr(std::string& strString, std::wstring& wsString, unsigned int uCodePage) 2 { 3 int len = 0; 4 wchar_t* buffer = nullptr; 5 6 len = MultiByteToWideChar(uCodePage, NULL, strString.c_str(), static_cast<int>(strString.size()), NULL, NULL); 7 buffer = new wchar_t[len + 1]; 8 MultiByteToWideChar(uCodePage, NULL, strString.c_str(), static_cast<int>(strString.size()), buffer, len); 9 buffer[len] = L'\0'; 10 wsString = buffer; 11 12 delete[] buffer; 13 }
这个new可不可以去掉呢?这样的话buffer指针和delete也可以去掉了,性能应该有一丢丢提升
std::string有一个resize方法可以改变string分配的缓冲区大小
同时配合data方法来获取缓冲区的指针,这样可以实现一个char*数组效果的缓冲区。
但是注意的是string内部默认是分配了一个较小的缓冲区,如果resize的大小比较小
data方法的指针仍然不变,但是如果resize比较大,data返回的指针会变化
也就是会释放旧缓冲区,重新分配缓冲区。
这个大小的界限在vc上是16,也就是大于等于16的resize会重新分配缓冲区。
同时也就提醒我们,不要认为data和c_str返回的地址总是不变的。
如果是resize小于当前字符串长度,会直接截断字符串,也就是在目标长度的缓冲区补0,暂时没发现会进行重新分配。
resize还有一点,resize的长度默认是不包含字符串结束符号 \0 的,也就是resize(5),实际上会分配6的空间,最后一个字节补0
对于wstring则是补充\0\0
resize的第二个参数是填写补充的字符,resize(10,'x'),如果比原始字符串长,则会补充x字符,往小resize不会,而且依然会在最后补充结束符。
最终优化的代码(仅演示,一些错误处理没写)
1 void CVTString::StrToWStr(std::string& strString, std::wstring& wsString, unsigned int uCodePage) 2 { 3 int charCount = MultiByteToWideChar 4 ( 5 uCodePage, NULL, strString.c_str(), static_cast<int>(strString.size()), NULL, NULL 6 ); 7 8 if (charCount == 0) return; 9 10 wsString.resize(charCount); 11 MultiByteToWideChar 12 ( 13 uCodePage, NULL, strString.c_str(), static_cast<int>(strString.size()), const_cast<wchar_t*>(wsString.data()), charCount 14 ); 15 }
2024年4月29日 :
不过以上代码还是有个性能问题的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!