【问题标题】:How to read a UTF-16 text file in C++17如何在 C++17 中读取 UTF-16 文本文件
【发布时间】:2019-06-23 11:32:01
【问题描述】:

我对 C++ 很陌生。我想在 Visual Studio 2019 中读取 C++17 中的 UTF-16 文本文件。

我在互联网上尝试了几种方法(包括 StackOverflow),但都没有奏效,其中一些无法编译(我认为它们只支持较旧的编译器)。

我正在尝试在不使用任何第三方库的情况下实现这一目标。

这会读取一个文本文件,但它有一些奇怪的字符和每个字母之间的空格。

// open file for reading
std::wifstream istrm(filename, std::ios::binary);
if (!istrm.is_open()) {
    std::cout << "failed to open " << filename << '\n';
}
else {
    std::wstring s;
    std::getline(istrm, s);
    std::wcout << s << std::endl;
}

然后我使用以下库找到了一些解决方案

#include <locale>
#include <codecvt>

// open file for reading
std::wifstream istrm(filename, std::ios::binary);
istrm.imbue(std::locale(istrm.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
if (!istrm.is_open()) {
    std::cout << "failed to open " << filename << '\n';
}
else {
    std::wstring s;
    std::getline(istrm, s);
    std::wcout << s << std::endl;
}

这次它甚至没有编译,在std::codecvt_utf16行出现以下错误:

错误 C4996 'std::codecvt_utf16':警告 STL4017:std::wbuffer_convert、std::wstring_convert 和标头(包含 std::codecvt_mode、std::codecvt_utf8、std::codecvt_utf16 和 std::codecvt_utf8_utf16 ) 在 C++17 中已弃用。 (不推荐使用 std::codecvt 类模板。)C++ 标准不提供等效的不推荐使用的功能。考虑改用 MultiByteToWideChar() 和 WideCharToMultiByte() 。您可以定义 _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING 或 _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS 以确认您已收到此警告。

如果有人可以为此提供解决方案,我将不胜感激。

提前致谢。

【问题讨论】:

  • 获取外部 Unicode 库。
  • @cyberbisson 我也添加了错误,它说要使用MultiByteToWideChar() ,我已经按照教程尝试过,但无法让它工作。(我很新C++)
  • 这不是错误。它将显示此警告至少十年,这就是使用具有 1-800 支持电话号码的 C++ 编译器的好处。所以只需#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING 继续你的生活。
  • 在 Windows 上,你不需要做任何编码转换,也不需要任何外部库来完成这个任务。以二进制模式创建std::ifstream,然后只需将整个文件读入std::wstring 即可。假设您只想阅读UTF-16 LE。对于UTF-16 BE(在 Windows 上很少使用),您需要每 2 个字节交换一次。
  • 微软的fopen也可以用来读取UTF编码的文件;例如fopen("newfile.txt", "rt+, ccs=UTF-16LE").

标签: c++ visual-c++ unicode c++17 utf-16


【解决方案1】:

首先,阅读Does std::wstring support UTF-16 and UTF-32 on Windows?Is 16-bit wchar_t formally valid for representing full Unicode?等相关问题。

如果您想要的只是将字符串读/写为您已经知道其编码为 UTF-16 的 blob,而无需执行任何转换或操作,并且您在 Windows 上的 Visual Studio 2019 等环境中,@ 987654323@,那么就可以使用C++宽字符串和流了。

现在,如果您需要执行转换、支持多种编码、在字符串中迭代(对于迭代的某些定义),或者一般来说任何不平凡的事情,如果您想留在 C ++17。 C++ 标准委员会已经为 Unicode 建立了一个工作组,因此希望在未来几年看到该领域的一些改进。目前,您需要使用诸如 MultiByteToWideCharWideCharToMultiByte 之类的 Win32 函数,或诸如 International Components for Unicode (ICU) 或 Boost 的 Locale 之类的外部库。

【讨论】:

  • 您好,谢谢您的回答,我再试试MultiByteToWideCharWideCharToMultiByte 的方法,看看,我之前试过了,还是不行。
  • @LukeWilliam 不客气!它们不难使用——如果你有问题,请用失败的代码打开另一个问题,我们可以看看 :-) 通常,你会想要调用 MultiByteToWideChar/WideCharToMultiByte 函数两次:首先你找出转换后的最终长度,然后为它分配内存,然后再次调用它,将实际结果写入缓冲区。
猜你喜欢
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 2016-07-02
  • 2012-08-20
相关资源
最近更新 更多