c++ - 在 C++ 中读取 UTF-16 文件

标签 c++ utf-16

我正在尝试读取一个包含 BOM 的 UTF-16LE 编码的文件。 我试过这段代码

#include <iostream>
#include <fstream>
#include <locale>
#include <codecvt>

int main() {

  std::wifstream fin("/home/asutp/test");
  fin.imbue(std::locale(fin.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
  if (!fin) {
    std::cout << "!fin" << std::endl;
    return 1;
  }
  if (fin.eof()) {
    std::cout << "fin.eof()" << std::endl;
    return 1;
  }
  std::wstring wstr;
  getline(fin, wstr);
  std::wcout << wstr << std::endl;

  if (wstr.find(L"Test") != std::string::npos) {
    std::cout << "Found" << std::endl;
  } else {
    std::cout << "Not found" << std::endl;
  }

  return 0;
}

该文件可以包含拉丁文和西里尔文。我创建了一个带有字符串“Test тест”的文件。这段代码返回我

/home/asutp/CLionProjects/untitled/cmake-build-debug/untitled

Not found

Process finished with exit code 0

我在 Linux Mint 18.3 x64、Clion 2018.1 上

尝试过

  • gcc 版本 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
  • clang 版本 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
  • clang 版本 5.0.0-3~16.04.1 (tags/RELEASE_500/final)

最佳答案

理想情况下,您应该以 UTF8 格式保存文件,因为 Window 具有更好的 UTF8 支持(除了在控制台窗口中显示 Unicode),而 POSIX 对 UTF16 的支持有限。即使是 Microsoft 产品也支持 UTF8 在 Windows 中保存文件。

作为替代方案,您可以将 UTF16 文件读入缓冲区并将其转换为 UTF8 ( std::codecvt_utf8_utf16 )

std::ifstream fin("utf16.txt", std::ios::binary);
fin.seekg(0, std::ios::end);
size_t size = (size_t)fin.tellg();

//skip BOM
fin.seekg(2, std::ios::beg);
size -= 2;

std::u16string u16((size / 2) + 1, '\0');
fin.read((char*)&u16[0], size);

std::string utf8 = std::wstring_convert<
    std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(u16);

或者
std::ifstream fin("utf16.txt", std::ios::binary);

//skip BOM
fin.seekg(2);

//read as raw bytes
std::stringstream ss;
ss << fin.rdbuf();
std::string bytes = ss.str();

//make sure len is divisible by 2
int len = bytes.size();
if(len % 2) len--;

std::wstring sw;
for(size_t i = 0; i < len;)
{
    //little-endian
    int lo = bytes[i++] & 0xFF;
    int hi = bytes[i++] & 0xFF;
    sw.push_back(hi << 8 | lo);
}

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::string utf8 = convert.to_bytes(sw);

关于c++ - 在 C++ 中读取 UTF-16 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50696864/

相关文章:

c++ - 如何在 Visual Studio 中重命名资源?

mysql - 在 MySQL 中将 UTF16 转换为 UTF8

使用 ICU 和 Nana GUI 库的 C++ - 字符串转换?

iphone - 将 plist utf-8 值读取为 utf-16

c++ - 获取一个类的所有继承类

c++ - 即使输入正确的内容,程序始终会引发异常

c# - 使用托管 C++ 包装器将字符串从 C# 传递到非托管 C#

python - 如何从 Python 3 中的 UTF-16 代码点获取字符?

c# - URL 编码 ASCII/UTF16 字符

C++ 代码执行缓慢