嗨,我试图将unicode字符串输出到带有iostreams的控制台并失败.
我发现了这一点: 在c ++控制台应用程序中使用unicode字体 ,这个代码片段有效.
SetConsoleOutputCP(CP_UTF8);
wchar_t s[] = L"èéøÞ????æ?a";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize];
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m);
Run Code Online (Sandbox Code Playgroud)
但是,我没有找到任何方法来使用iostream正确输出unicode.有什么建议?
这不起作用:
SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl;
Run Code Online (Sandbox Code Playgroud)
编辑 我找不到任何其他解决方案,而不是在流中包装此片段.希望,有人有更好的想法.
//Unicode output for a Windows console
ostream &operator-(ostream &stream, const wchar_t *s)
{
int bufSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char *buf = …Run Code Online (Sandbox Code Playgroud) 我正在阅读"C++ Cookbook",其中包含以下代码段:
// cout << s << std::endl; // You shouldn't be able to
wcout << ws << std::endl; // run these at the same time
Run Code Online (Sandbox Code Playgroud)
如果您对查看实际示例感兴趣,可以在此处找到Google图书页面的链接.
此外,我发现这个SO问题似乎表明混合wcout和cout是可以的.有人可以向我解释一下这个评论的内容吗?
编辑
从C++标准[27.4.1]:
对相应的宽字符和窄字符流的混合操作遵循与在FILE上混合此类操作相同的语义,如ISO C标准的修订1中所规定的.
从C标准[7.19.2]:
每个流都有一个方向.在流与外部文件关联之后,但在对其执行任何操作之前,该流没有方向.一旦将宽字符输入/输出功能应用于没有方向的流,该流就变为面向广泛的流.类似地,一旦将字节输入/输出功能应用于没有方向的流,该流就变成面向字节的流.只有调用freopen函数或fwide函数才能改变流的方向.(成功拨打freopen会删除任何方向.)
字节输入/输出功能不应用于面向广泛的流,宽字符输入/输出功能不应用于面向字节的流.
所以,标准似乎说你不应该混合它们.但是,我从这篇文章中找到了这句话:
对于Visual C++ 10.0,fwide函数被记录为未实现.从实际的角度来看,至少在输出整行的水平上,它显然可以很好地混合使用cout和wcout.因此,很高兴,Visual C++显然只是忽视了标准的要求,并没有维护一个不切实际的显式C FILE流方向.
而且,关于gcc,我从这里找到了这个引用:
这是一个(新的)功能,而不是一个bug,请参阅libstdc ++/11705,以及在C标准(C99,7.19)中的流方向搜索.简而言之,您不能混合面向字节和面向广泛的I/O. 目前,由于 libstdc ++/11705中指出的bug,你可以通过调用std :: ios :: sync_with_stdio(false)获得接近你期望的东西.在你的程序的开头.
对于在英语Windows(XP,Vista或7)上使用Visual Studio 2008编译的C++控制台应用程序.是否可以打印到控制台并使用cout或wcout正确显示UTF-8编码的日语?
我重新安装了Code :: Blocks(我安装了一个用于Windows 7的GCC编译器(codeblocks-10.05mingw-setup.exe)).然后我尝试编译这个非常简单的代码:
int wmain(int argc, wchar_t* argv[])
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误消息:
C:\研发\ IDE \代码块\ MinGW的\ BIN ..\LIB\GCC \的mingw32\4.4.1 ......\libmingw32.a(main.o),此:main.c中|| 未定义的引用`WinMain @ 16'| || ===构建完成:1个错误,0个警告=== |
当我尝试使用main()条目运行我的代码时,它会按预期运行而不会出现任何错误或警告.我如何wmain()在我的代码中使用?我需要做哪些修改?
当我用外国人写字时(法语......)似乎有问题
例如,如果我要求输入std :: string或char [],如下所示:
std::string s;
std::cin>>s; //if we input the string "café"
std::cout<<s<<std::endl; //outputs "café"
Run Code Online (Sandbox Code Playgroud)
一切都好.
虽然字符串是硬编码的
std::string s="café";
std::cout<<s<<std::endl; //outputs "cafÚ"
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?C++支持哪些字符,如何使其正常工作?它与我的操作系统(Windows 10)有关吗?我的IDE(VS 15)?还是用C++?
附录我自己的初步答案出现在问题的底部。
我是一个古老的VC6 C ++ / MFC项目转换为VS2013和Unicode的基础上,建议在utf8everywhere.org。
一路上,我一直在研究 Unicode、UTF-16、UCS-2、UTF-8、Unicode 和 UTF-8 的标准库和 STL 支持(或者,更确切地说,标准库缺乏支持)、ICU、Boost .Locale,当然还有需要 UTF-16 的 Windows SDK 和 MFC 的 API wchar。
在我研究上述问题的过程中,一个问题不断出现,我无法以清晰的方式回答我满意的问题。
考虑 C 库函数mbstowcs。此函数具有以下签名:
size_t mbstowcs (wchar_t* dest, const char* src, size_t max);
Run Code Online (Sandbox Code Playgroud)
第二个参数src是(根据文档)a
带有要解释的多字节字符的 C 字符串。多字节序列应从初始移位状态开始。
我的问题是关于这个多字节字符串。我的理解是多字节字符串的编码可能因字符串而异,并且标准未指定编码。MSVC 文档似乎也没有为此函数指定特定的编码。
我此时的理解是,在 Windows 上,这个多字节字符串应该使用活动语言环境的 ANSI 代码页进行编码。但我的清晰度在这一点上开始消退。
我一直想知道源代码文件本身的编码是否会对的行为产生影响mbstowcs,至少在 Windows 上。 而且,对于上面的代码片段,我也对编译时发生的情况与运行时 …