c++ - 在 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::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);
推荐阅读
- .net - 不能把进程带到前面
- c++11 - C ++中的用户定义文字运算符错误
- python - 为什么 re.match() 在这里不能正常工作?
- c# - 带有 DateTime 列的 LINQ 查询,groupby 仅带有第二个变量的日期,计算每个子组的总条目
- javascript - 如何将电子表格中的范围作为图像复制到 Google 幻灯片?
- reactjs - react js中的“全局或本地安装包”是什么意思?
- laravel - 为什么这个 Laravel 播种机会失败?
- python - 如何修复 virtualenvwrapper_run_hook:12: 和 virtualenvwrapper.sh 问题...?
- rest - Quarkus Resources Not Found 当相同的路径注解位于两个不同的类时
- c++ - std::cout 一次可以输出多少个字符或字符或数据字节?