使用printf将em dash打印到控制台窗口? 一个简单的问题:我正在编写C++的聊天室程序(但主要是C风格),我正试图打印“帮助显示一个命令列表…”到输出窗口。虽然我可以使用两个连字符(-)来实现大致相同的效果,但我宁愿使用em破折号(-)printf()似乎不支持打印em破折号。相反,控制台只是在原处打印字符ù,尽管直接在提示符中输入em破折号效果很好
如何显示这个简单的Unicode字符 查看Windows alt键代码,我发现alt+0151是“-”,alt+151是“ù”,这很有趣。这与我的问题有关,还是一个简单的巧合 windows是unicode(UTF-16)系统。控制台unicode也是如此。如果您想要打印unicode文本,您需要(而且这是最有效的)使用 在这种情况下,二进制文件将是宽字符使用printf将em dash打印到控制台窗口? 一个简单的问题:我正在编写C++的聊天室程序(但主要是C风格),我正试图打印“帮助显示一个命令列表…”到输出窗口。虽然我可以使用两个连字符(-)来实现大致相同的效果,但我宁愿使用em破折号(-)printf()似乎不支持打印em破折号。相反,控制台只是在原处打印字符ù,尽管直接在提示符中输入em破折号效果很好,c++,c,windows,visual-studio,windows-console,C++,C,Windows,Visual Studio,Windows Console,如何显示这个简单的Unicode字符 查看Windows alt键代码,我发现alt+0151是“-”,alt+151是“ù”,这很有趣。这与我的问题有关,还是一个简单的巧合 windows是unicode(UTF-16)系统。控制台unicode也是如此。如果您想要打印unicode文本,您需要(而且这是最有效的)使用 在这种情况下,二进制文件将是宽字符-(2字节0x2014)并按原样打印 如果为输出控制台调用ansi(多字节)函数,如writeconolea或WriteFile,则控制台首先
-
(2字节0x2014
)并按原样打印
如果为输出控制台调用ansi(多字节)函数,如writeconolea
或WriteFile
,则控制台首先通过将多字节字符串转换为unicode,并将使用返回的值就地代码页。如果使用大于0x80的字符,这里(翻译)可能会出现问题
首先,编译器可能会给您警告:文件包含一个无法在当前代码页(数字)中表示的字符。以Unicode格式保存文件以防止数据丢失。(). 但即使将源文件保存为Unicode格式,也可以:
wprintf(L"ù"); // no warning
printf("ù"); //warning C4566
因为L“ù”
在二进制文件中保存为宽字符字符串(原样)-这里一切正常,没有任何问题和警告。但是“ù”
保存为字符字符串(单字节字符串)。编译器需要将宽字符串“ù”从源文件转换为二进制(.obj文件,链接器从该文件创建pe)。和编译器一起使用CP_ACP(当前系统默认的Windows ANSI代码页)
那么,如果你说callprintf(“ù”)代码>
unicode字符串“ù”将转换为多字节
WideCharToMultiByte(CP\u ACP,)
这将在编译时进行。生成的多字节字符串将保存在二进制文件中
控制台将运行时字符串转换为多字节字符串
通过MultiByteToWideChar(GetConsoleOutputCP(),…)
和
打印此字符串
因此您得到了两种转换:unicode->CP\u ACP->multi-byte->GetConsoleOutputCP()->unicode
默认情况下GetConsoleOutputCP()==CP\u OEMCP!=CP_ACP
即使您在编译程序的计算机上运行该程序。(特别是在另一台计算机上,使用另一个CP\u OEMCP
)
不兼容转换中的问题-使用了不同的代码页。但是,即使将控制台代码页更改为CP\u ACP
,转换也可能会错误地翻译某些字符
关于CRT apiwprintf
——接下来的情况是:
wprintf
首先使用内部当前值将给定字符串从unicode转换为多字节(注意crt区域设置独立于控制台区域设置,不同于控制台区域设置)。然后使用多字节字符串调用WriteFile
。控制台将此多字节字符串转换回unicode
unicode->current\u crt\u locale->multi-byte->GetConsoleOutputCP()->unicode
因此,为了使用wprintf
我们需要首先将当前crt区域设置设置为GetConsoleOutputCP()
但无论如何,我在这里查看(在我的comp上)屏幕上的-
,而不是-
。如果调用PrintString(L“-”),则--
也是如此代码>(在这之后使用了WriteConsoleW
)
所以,唯一可靠的方法是打印任何unicode字符(windows支持)-使用WriteConsoleWapi。windows是unicode(UTF-16)系统。控制台unicode也是如此。如果您想要打印unicode文本,您需要(而且这是最有效的)使用
在这种情况下,二进制文件将是宽字符-
(2字节0x2014
)并按原样打印
如果为输出控制台调用ansi(多字节)函数,如writeconolea
或WriteFile
,则控制台首先通过将多字节字符串转换为unicode,并将使用返回的值就地代码页。如果使用大于0x80的字符,这里(翻译)可能会出现问题
首先,编译器可能会给您警告:文件包含一个无法在当前代码页(数字)中表示的字符。以Unicode格式保存文件以防止数据丢失。(). 但即使将源文件保存为Unicode格式,也可以:
wprintf(L"ù"); // no warning
printf("ù"); //warning C4566
因为L“ù”
在二进制文件中保存为宽字符字符串(原样)-这里一切正常,没有任何问题和警告。但是“ù”
保存为字符字符串(单字节字符串)。编译器需要将宽字符串“ù”从源文件转换为二进制(.obj文件,链接器从该文件创建pe)。和编译器一起使用CP_ACP(当前系统默认的Windows ANSI代码页)
那么,如果你说callprintf(“ù”)代码>
unicode字符串“ù”将转换为多字节
WideCharToMultiByte(CP\u ACP,)
这将在编译时进行。生成的多字节字符串将保存在二进制文件中
控制台将运行时字符串转换为多字节字符串
通过MultiByteToWideChar(GetConsoleOutputCP(),…)
和
打印此字符串
所以你有两个转换
char sz[16];
sprintf(sz, ".%u", GetConsoleOutputCP());
setlocale(LC_ALL, sz);
wprintf(L"—");
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
int main()
{
//other stuff
_setmode(_fileno(stdout), _O_U16TEXT);
wprintf(L"#help — display a list of commands...");