下面是一些从UFT-8文件读取一行的代码:
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <locale>
#include <fstream>
#include <codecvt>
int main()
{
_setmode(_fileno(stdout), _O_U8TEXT);
auto inputFileStream = std::wifstream("input.txt");
const auto utf8Locale = std::locale(std::locale(), new std::codecvt_utf8<wchar_t>());
inputFileStream.imbue(utf8Locale);
std::wstring line;
std::getline(inputFileStream, line);
std::wcout << line << std::endl;
inputFileStream.close();
return 0;
}
当我使用Visual Studio Visual C ++编译器构建它时,得到了下一个结果:
测试τεστтест
符合预期。
当我将MinGW与GCC编译器一起使用时,我得到了
琀攀猀琀쐃딃쌃쐃䈄㔄䄄䈄
如您所知,这不是预期的结果。
OR
答案(感谢 Igor Tandetnik 和 Remy Lebeau ): 似乎,我们必须明确指定字节序模式,因为MSVC和GCC具有不同的默认值。所以
new std::codecvt_utf8<wchar_t, 0x10ffff, std::little_endian>()
应该使用。
固定代码:
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <locale>
#include <fstream>
#include <codecvt>
int main()
{
_setmode(_fileno(stdout), _O_U8TEXT);
auto inputFileStream = std::wifstream("input.txt");
const auto utf8Locale = std::locale(std::locale(), new std::codecvt_utf8<wchar_t, 0x10ffff, std::little_endian>());
inputFileStream.imbue(utf8Locale);
std::wstring line;
std::getline(inputFileStream, line);
std::wcout << line << std::endl;
inputFileStream.close();
return 0;
}
答案 0 :(得分:0)
对于第二个问题,一个选择是将utf16和带有std::w
前缀的东西的使用限制为需要与操作系统交换utf16编码的字符串的情况。当您在wmain
中接收参数,使用_wfopen
打开文件,调用Windows API函数等时,会发生这种情况。否则,您将使用{{1来存储,从用户那里获取并返回到用户utf8字符串。 }}类型(char
,char*
等)。可以使用std::string
和MultiByteToWideChar
完成utf8和utf16之间的转换,绕过了延迟的c ++编码api。效果不好的地方是控制台输入/输出。总体而言,如果用户设置了WideCharToMultiByte
和ttf字体,则可以将utf8输出到控制台。至少在Windows 7中,还必须确保不要在两个写调用之间分割字符,否则它将无法正确打印(这也意味着您不能使用chcp 65001
,因为msvcrt会调用{{1} }分别用于每个字节,而您需要使用std::cout
,putc
等);我听说这在Windows 10中已修复,但无法确认。据我所知,使用文件api从控制台读取utf8无效;如果需要的话,您需要检测stdin是否已附加到控制台,并改用控制台api。