即使名字是wofstream
意味着它是一个宽字符流,但事实并非如此。它仍然是一个char
使用区域设置中的转换面来转换的流wchars
to char
.
这是 cppreference 所说的:
所有文件 I/O 操作通过std::basic_fstream<CharT>
使用std::codecvt<CharT, char, std::mbstate_t>
流中渗透的语言环境的一个方面。
因此,您可以将全局区域设置设置为支持中文的区域设置,或者imbue
溪流。在这两种情况下,您都会得到一个字节流。
#include <locale>
//...
const std::locale loc = std::locale(std::locale(), new std::codecvt_utf8<wchar_t>);
Out.open(Path, ios::out);
Out.imbue(loc);
很遗憾std::codecvt_utf8
已被弃用[2 http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0618r0.html]。这个MSDN
杂志
文章解释了如何使用进行 UTF-8 转换MultiByteToWideChar
.
这里的微软/vcpkg https://github.com/Microsoft/vcpkg/commit/ca692e52cee55da2f9d65d66e5f3997f3a335743的变体to_utf8
转换:
std::string to_utf8(const CWStringView w)
{
const size_t size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr);
std::string output;
output.resize(size - 1);
WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr);
return output;
}
另一方面,您可以使用普通的二进制流并编写wstring
数据与write()
.
std::ofstream Out(Path, ios::out | ios::binary);
const uint16_t bom = 0xFEFF;
Out.write(reinterpret_cast<const char*>(&bom), sizeof(bom)); // optional Byte order mark
Out.write(reinterpret_cast<const char*>(chi.data()), chi.size() * sizeof(wchar_t));