我正在使用std :: fstream库,但发现它编写失败。原来,这是一个短划线。
wchar_t mdash[] = { 0x2014, 0x0000 };
std::wfstream os("filename.txt", std::ios_base::out| std::ios_base::trunc);
os << mdash;
assert(!os.bad()); // fails
我无法控制要转储到文件中的内容,因此我需要一种方法来正确地写出文件而不会崩溃。因此,我基于this answer编写了此函数。
void set_locale_on_stream(std::wfstream &os)
{
char* locale = setlocale(LC_ALL, "English"); // Get the CRT's current locale.
std::locale lollocale(locale);
setlocale(LC_ALL, locale); // Restore the CRT.
os.imbue(lollocale); // Now set the std::wcout to have the locale that we got from the CRT.
}
这行得通,除了现在我已经为我的数字添加了分组分隔符,并且它们是十六进制的,因此完全没有用!
有办法阻止这种情况发生吗?
答案 0 :(得分:1)
fs.imbue(std::locale(ofs.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>))
是设置语言环境所必需的,不幸的是codecvt_utf16
已过时,并且尚未替代。
相反,您可以以二进制模式打开文件并使用pubsetbuf
。请注意,如果您的文件开头没有2字节的BOM标记,则文本编辑器可能无法将其识别为UTF16-LE。
int foo()
{
wchar_t mdash[] = L"— Test";
const wchar_t *filename = L"filename.txt";
wchar_t wbuf[128];
std::wofstream fout(filename, std::ios::binary);
if(fout)
{
fout.rdbuf()->pubsetbuf(wbuf, 128);
//optional BOM
wchar_t bom[1] = { 0xFEFF };
fout.write(bom, 1);
fout << mdash;
fout.close();
}
std::wifstream fin(filename, std::ios::binary);
if(fin)
{
fin.rdbuf()->pubsetbuf(wbuf, 128);
//optional, skip BOM
std::wstring wstr;
if(fin >> wstr)
MessageBoxW(0, wstr.c_str(), 0, 0);
fin.close();
}
return 0;
}