如何获取数字以停止使用std :: wfstream库中的分组分隔符?

时间:2018-11-16 04:19:18

标签: c++ visual-c++ c++14 std c++17

我正在使用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.
}

这行得通,除了现在我已经为我的数字添加了分组分隔符,并且它们是十六进制的,因此完全没有用!

有办法阻止这种情况发生吗?

1 个答案:

答案 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;
}