如何使用C ++在Win上编写和读取UTF16文件

关于这个,关于SO有很多问题,但是大多数都没有提到写回wstring。 所以例如我发现这个阅读:

// open as a byte stream std::wifstream fin("/testutf16.txt", std::ios::binary); // apply BOM-sensitive UTF-16 facet fin.imbue(std::locale(fin.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>)); // read std::wstring ws; for(wchar_t c; fin.get(c); ) { std::cout << std::showbase << std::hex << c << '\n'; ws.push_back(c); } 

我尝试写类似的东西:

  std::wofstream wofs("/utf16dump.txt", std::ios::binary); wofs.imbue(std::locale(wofs.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>)); wofs << ws; 

但它会产生垃圾,(或Notpad ++和vim不能解释它)。 如标题为“我赢了,本地C ++,VS 2010”中所述。

input文件:

 t€stUTF16✡ test 

这是什么结果:

 t€stUTF16✡ test 

转换为hex:

 0000000: 7400 ac20 7300 7400 5500 5400 4600 3100 t.. stUTF1. 0000010: 3600 2127 0d00 0a00 7400 6500 7300 7400 6.!'....test 0000020: 0a ... 

vim正常输出:

t ^ @ s ^ @ t ^ @ U ^ @ T ^ @ F ^ @ 1 ^ @ 6 ^ @!'^ M ^ @ ^ @ t ^ @ e ^ @ s ^ @ t ^ @

编辑:我结束了使用UTF8。 安德烈Alexandrescu说,这是最好的编码,所以没有大的损失。 🙂

Solutions Collecting From Web of "如何使用C ++在Win上编写和读取UTF16文件"

你的类似的代码 – 不是。 你删除了std::ios::binary风格,尽管文档说的事实

字节流应该写入二进制文件; 如果写入文本文件可能会损坏。

在ASCII模式下NL-> CRLF转换不会对UTF-16文件做很多事情,因为它会插入一个字节0x0D而不是两个字节0x00 0x0D。

如果你使用C++11标准,很容易(因为有很多附加的东西像"utf8" ,它永远解决了这个问题)。

但是,如果您想要使用较老的标准使用多平台代码,则可以使用此方法来写入流:

  1. 阅读有关UTF转换器的文章
  2. 从上面的源代码添加stxutif.h到你的项目
  3. 以ANSI模式打开文件,并将BOM添加到文件的开头,如下所示:

     std::ofstream fs; fs.open(filepath, std::ios::out|std::ios::binary); unsigned char smarker[3]; smarker[0] = 0xEF; smarker[1] = 0xBB; smarker[2] = 0xBF; fs << smarker; fs.close(); 
  4. 然后以UTF文件格式打开文件并在其中写下你的内容:

     std::wofstream fs; fs.open(filepath, std::ios::out|std::ios::app); std::locale utf8_locale(std::locale(), new utf8cvt<false>); fs.imbue(utf8_locale); fs << .. // Write anything you want... 

对于输出,你想使用generate_header而不是consume_header

请参阅http://en.cppreference.com/w/cpp/locale/codecvt_mode