繁体   English   中英

用c ++读取UTF-16文件

[英]Reading UTF-16 file in c++

我正在尝试读取具有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(标签/ RELEASE_380 / final)
  • clang版本5.0.0-3~16.04.1(标签/ RELEASE_500 / final)

理想情况下,您应该以UTF8保存文件,因为Window具有更好的UTF8支持(除了在控制台窗口中显示Unicode),而POSIX具有有限的UTF16支持。 甚至微软的产品都支持使用UTF8来保存Windows中的文件。

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

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

//skip BOM
fin.seekg(2, 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); 

替换为 - std::wstring::npos (不是std::string::npos ) - ,并且您的代码必须工作:

...
 //std::wcout << wstr << std::endl;

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM