在std::string和std::wstring之间转换的多平台方式
Multiplatform way to convert between std::string and std::wstring
我当前正在使用Windows API的方法MultiByteToWideChar
和WideCharToMultiByte
在std::string
和std::wstring
之间进行转换。
我正在"多平台化"我的代码,删除Windows依赖项,所以我想知道上面方法的替代方案。具体来说,使用boost将非常棒。我可以使用哪些方法?这是我目前使用的代码:
const std::wstring Use::stow(const std::string& str)
{
if (str.empty()) return L"";
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstrTo( size_needed, 0 );
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
return wstrTo;
}
const std::string Use::wtos(const std::wstring& wstr)
{
if (wstr.empty()) return "";
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo( size_needed, 0 );
WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
基本上,使用<cstdlib>
,您可以获得与Joachim Pileborg所提到的类似的实现。只要您已经将区域设置为您想要的任何位置(例如:setlocale( LC_ALL, "en_US.utf8" );
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0)
=>mbstowcs(nullptr, data(str), size(str))
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed)
=>mbstowcs(data(wstrTo), data(str), size(str))
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL)
=>wcstombs(nullptr, data(wstr), size(wstr))
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL)
=>wcstombs(data(strTo), data(wstr), size(wstr))
编辑:
c++11要求字符串连续分配,如果您正在跨平台编译,这可能很重要,因为以前的标准不要求string
连续分配。以前调用&str[0]
、&strTo[0]
、&wstr[0]
或&wstrTo[0]
可能会导致问题
由于c++17现在是公认的标准,我改进了我建议的替换,使用data
,而不是取消对字符串前面的引用。
从您的代码来看,您似乎正在使用utf-8编码。要使用utf-8,请查看UTF8-CPPhttp://utfcpp.sourceforge.net/它是一个只有标题的库
看看utf8to32函数。(请注意,在Windows上,wchar_t是16位,在其他平台(如linux)上,它通常是32位)
const std::wstring Use::stow(const std::string &s)
{
return std::wstring(s.begin(), s.end());
}
const std::string Use::wtos(const std::wstring &ws)
{
return std::string(ws.begin(), ws.end());
}
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 引用 std::any 或 not_yet_in_std::whatever 的惯用方式是什么?
- 如何以滑动窗口方式从 std::bitset 读取位并将它们转换为 int?
- 从 T 创建 std::future 的最佳方式<T>
- 将 std::array 推回 std::vector N 次的优雅方式
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- 是否可以以编程方式构造 std::initializer_list?
- 如果 std::numeric_limits<float>::is_iec559 为真,这是否意味着我可以以明确定义的方式提取指数和尾数?
- 访问 std::multimap 值的最佳方式?
- 是否可以以编程方式初始化 constexpr std::array 成员
- 如何使用 std::sort 以'custom'的方式就地对数组进行排序
- 为什么标准库不以无锁的方式为 8 字节以下的结构实现 std::atomic?
- 最快的方式 std::vector<Derived> to std::vector<Base>
- 是否可以让 std::vector<char> 使用选定的内存对齐方式分配内存
- 以C 标准的方式实现STD :: Malloc
- std::getline(std::cin, string) 可能因键盘输入失败的方式
- 访问"std::variant"的不安全、"noexcept"和无开销方式
- 拥有 std::map 的最佳方式,我可以在其中定义如果没有键时返回的内容
- 有没有一种透明的方式来在 std 容器中使用unique_ptr
- 这种创建带有指向实例的指针的分离 std::thread 的方式是错误的吗?