且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在 Windows 控制台上输出 Unicode 字符串

更新时间:2021-10-20 22:28:04

我/我们在大多数(跨平台)应用程序/项目中使用的一般策略是:我们只在任何地方使用 UTF-8(我的意思是真正的标准).我们使用 std::string 作为容器,我们只是将 一切 解释为 UTF8.我们也以这种方式处理所有文件 IO,即我们期望 UTF8 并保存 UTF8.如果我们从某处得到一个字符串并且我们知道它不是 UTF8,我们会将其转换为 UTF8.

The general strategy I/we use in most (cross platform) applications/projects is: We just use UTF-8 (I mean the real standard) everywhere. We use std::string as the container and we just interpret everything as UTF8. And we also handle all file IO this way, i.e. we expect UTF8 and save UTF8. In the case when we get a string from somewhere and we know that it is not UTF8, we will convert it to UTF8.

我们偶然发现 WinUTF16 的最常见情况是文件名.所以对于每个文件名处理,我们总是将 UTF8 字符串转换为 WinUTF16.如果我们在目录中搜索文件,也是另一种方式.

The most common case where we stumble upon WinUTF16 is for filenames. So for every filename handling, we will always convert the UTF8 string to WinUTF16. And also the other way if we search through a directory for files.

在我们的 Windows 版本中并没有真正使用控制台(在 Windows 版本中,所有控制台输出都被包装到一个文件中).因为我们到处都有 UTF8,所以我们的控制台输出也是 UTF8,这对于大多数现代系统来说都很好.而且 Windows 控制台日志文件的内容是 UTF8,Windows 上的大多数文本编辑器都可以毫无问题地读取它.

The console isn't really used in our Windows build (in the Windows build, all console output is wrapped into a file). As we have UTF8 everywhere, also our console output is UTF8 which is fine for most modern systems. And also the Windows console log file has its content in UTF8 and most text-editors on Windows can read that without problems.

如果我们更多地使用 WinConsole 并且我们非常关心所有特殊字符是否正确显示,我们可能会编写一些自动管道处理程序,我们将其安装在 fileno=0 和真正的 stdout 将按照您的建议使用 WriteConsoleW(如果真的没有更简单的方法).

If we would use the WinConsole more and if we would care a lot that all special chars are displayed correctly, we maybe would write some automatic pipe handler which we install in between fileno=0 and the real stdout which will use WriteConsoleW as you have suggested (if there is really no easier way).

如果你想知道如何实现这样的自动管道处理程序:我们已经为所有类似 POSIX 的系统实现了这样的东西.该代码可能无法在 Windows 上正常工作,但我认为应该可以移植它.我们当前的管道处理程序类似于 tee 所做的.IE.如果您执行 cout <<你好"<<endl,它将同时打印在 stdout 和一些日志文件中.看看 代码,如果您对这是如何完成的感兴趣的话.

If you wonder about how to realize such automatic pipe handler: We have implemented such thing already for all POSIX-like systems. The code probably doesn't work on Windows as it is but I think it should be possible to port it. Our current pipe handler is similar to what tee does. I.e. if you do a cout << "Hello" << endl, it will both be printed on stdout and in some log-file. Look at the code if you are interested how this is done.