如何在C ++ 17中读取UTF-16文本文件

时间:2019-06-23 11:32:01

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

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

我已经在Internet上尝试了几种方法(包括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 :: code8 )在C ++ 17中已弃用。 (不建议使用std :: codecvt类模板。)C ++标准不提供等效的不建议使用的功能;请参见参考。考虑改用MultiByteToWideChar()和WideCharToMultiByte()。您可以定义_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING或_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS来确认您已收到此警告。

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

谢谢。

1 个答案:

答案 0 :(得分:1)

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

如果您想要的只是将字符串读/写为blob,而您已经知道其编码为UTF-16,而不执行任何转换或操作,并且您所处的环境类似于Windows上的Visual Studio 2019,{ {3}},则可以使用C ++宽字符串和流。

现在,如果您需要执行转换,支持多种编码,在字符串中进行迭代(对于迭代的某些定义),或者通常来说是不重要的事情,那么如果您想保留在C中,那您现在就不走运了++ 17。 C ++标准委员会已经为Unicode建立了一个工作组,因此希望在未来几年中在这方面看到一些改进。目前,您将需要使用诸如MultiByteToWideCharWideCharToMultiByte之类的Win32函数,或诸如Unicode国际组件(ICU)或Boost的语言环境之类的外部库。