C++ 将unicode字符/字符串写入文件

C++ 将unicode字符/字符串写入文件,c++,file,wchar,wofstream,C++,File,Wchar,Wofstream,我试图用std::wofstream将unicode字符写入文件,但put或write函数不写入任何字符 示例代码: #include <fstream> #include <iostream> int main() { std::wofstream file; file.open("output.txt", std::ios::app); if (file.is_open()) { wchar_t test = L'й'

我试图用
std::wofstream
将unicode字符写入文件,但
put
write
函数不写入任何字符

示例代码:

#include <fstream>
#include <iostream>

int main()
{
    std::wofstream file;
    file.open("output.txt", std::ios::app);
    if (file.is_open())
    {
        wchar_t test = L'й';
        const wchar_t* str = L"фывдлао";
        file.put(test);
        file.write(str, sizeof(str));
        file.close();
    }
    else
    {
        std::wcerr << L"Failed to open file" << std::endl;
    }

    std::cin.get();
    return 0;
}

应用代码更正后,我看到
无法写入
,但我仍然不明白需要做什么才能写入宽字符串和字符?

第一个问题立即出现:
put
无法写入宽字符,流将失败,但您永远不会检查第一次写入是否成功:

file.put(test);
if(not file.good())
{
    std::wcerr << L"Failed to write" << std::endl;
}
file.put(测试);
if(不是file.good())
{

std::wcerr我这样做,不需要外部字符串库,比如QString

仅使用std库和c++11

#include <iostream>
#include <locale>
#include <codecvt>
#include <fstream>
#include <Windows.h>

int main()
{
    std::wofstream file;
    // locale object is responsible of deleting codecvt facet!
    std::locale loc(std::locale(), new std::codecvt_utf16<wchar_t> converter);

    file.imbue(loc);
    file.open("output.txt"); // open file as UTF16!

    if (file.is_open())
    {
        wchar_t BOM = static_cast<wchar_t>(0xFEFF);
        wchar_t test_char = L'й';
        const wchar_t* test_str = L"фывдлао";

        file.put(BOM);
        file.put(test_char);
        file.write(test_str, lstrlen(test_str));

        if (!file.good())
        {
            std::wcerr << TEXT("Failed to write") << std::endl;
        }

        file.close();
    }
    else
    {
        std::wcerr << TEXT("Failed to open file") << std::endl;
    }

    std::wcout << TEXT("Done!") << std::endl;

    std::cin.get();
    return 0;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
std::wofstream文件;
//locale对象负责删除codecvt方面!
std::locale loc(std::locale(),新的std::codevt_utf16转换器);
文件.imbue(loc);
file.open(“output.txt”);//以UTF16格式打开文件!
if(file.is_open())
{
wchar\u t BOM=静态浇铸(0xFEFF);
wchar_t test_char=L';
const wchar_t*test_str=L“фыцаа”;
文件放置(BOM);
file.put(test_char);
write(test_str,lstrlen(test_str));
如果(!file.good())
{

std::wcerr谢谢,我用更正更新了我的问题…我需要做什么来编写宽字符串?你说
put
不接受宽字符,但我看到它需要一个
wchar\t
参数,因为它是
wofstream
宽版本,所以为什么它不工作?@zebanovich,尽管它是一个“宽版本”版本它仍然在“单一”上运行字符。所以写宽字符的唯一方法是以二进制模式打开文件并使用
write
方法。好的,我尝试了
std::ios::binary
并只使用
write
方法,但它仍然不能写出宽字符串。设置了失败位。@zebanovich您确定打开了正常的流吗(非宽流,每次不能缩小宽字符时都会失败)在二进制模式下,我也尝试过,使用正常流,即<代码> STD::OFFROWS/CODE>导致错误输出。<代码>警告C4244:“参数”:从“W查尔夫T”转换为“E-ELAM”,可能丢失数据< /代码>:C++中的宽字符是有问题的,AFAK WCHARGYT可能会导致更多的问题得到解决。n、 像QString一样,可能是一个更安全的选择。QString?肯定有一种方法可以将unicode与标准库或本机OS API一起使用?我只是从来没有遇到过以意外方式工作的函数/对象的宽版本出现这种问题。例如,offstream的宽版本处理
char
而不是
wchar\t
什么这背后的逻辑是什么?@Frax
QString
也是基于
wchar\u t
的。它唯一的优势是一个来自同一个源的稳定版本的ABI。@重复数据消除器一方面,QString可以正确地、开箱即用地处理UTF-8。一般来说,它是可移植的,而wchar\u不是很多,因为它在不同的平台上有不同的大小s、 我不确定它在实践中是如何工作的。关键是,cpp标准对wchar____________________________________________@ FRAX抱歉,我错了。QStand是基于自己的UTF-16代码单元类,而不是在代码> WCARYTT 。注意:代码> STD::CODECVTTUTF16尚未被替换。您可以考虑将文件保存在UTF8格式中,将其转换为UTF16的WiAPI。
#include <iostream>
#include <locale>
#include <codecvt>
#include <fstream>
#include <Windows.h>

int main()
{
    std::wofstream file;
    // locale object is responsible of deleting codecvt facet!
    std::locale loc(std::locale(), new std::codecvt_utf16<wchar_t> converter);

    file.imbue(loc);
    file.open("output.txt"); // open file as UTF16!

    if (file.is_open())
    {
        wchar_t BOM = static_cast<wchar_t>(0xFEFF);
        wchar_t test_char = L'й';
        const wchar_t* test_str = L"фывдлао";

        file.put(BOM);
        file.put(test_char);
        file.write(test_str, lstrlen(test_str));

        if (!file.good())
        {
            std::wcerr << TEXT("Failed to write") << std::endl;
        }

        file.close();
    }
    else
    {
        std::wcerr << TEXT("Failed to open file") << std::endl;
    }

    std::wcout << TEXT("Done!") << std::endl;

    std::cin.get();
    return 0;
}