我正在使用Dev C ++,Windows 7。
我正在尝试使用以下方法打印出非ascii字符:
char a='\uwxyz';
例如:
#include <locale.h>
#include <iostream>
#include <cstdlib>
#include <windows.h>
#include <conio.h>
#include <stdio.h>
using namespace std;
int main()
{
setlocale(LC_ALL,"en_US.UTF-8");
char a='\u0041'; //Should display 'A'
cout<<a<<endl;
a='\u2639'; //Should display '☹'
cout<<a<<endl;
system("PAUSE");
}
在此示例中,大写A正确显示。使用wxDev,☹字符只显示任何内容。使用Dev(我需要用于最终程序),我会得到一个扩展的ascii字符(它是一个类似于symbol的符号,但有多个符号看起来像那样,我无法分辨它是什么)。
在Dev和wxDev中,☹显示为?。
我在初步搜索了如何正确显示unicode字符之后添加了setlocale,但我还没有找到任何解决这个问题的方法。
我无法使用其他编译器或修改系统设置来使其工作。 (是的,这是一个学校项目。不,项目不需要特殊字符;我只是想让它看起来更好。)如果不修改这些设置就无法工作,那也是有用的信息。
提前感谢您的帮助。
编辑:使用Dev,而不是wxDev,
char a='\u0041'; //should be A
cout<<a;
我收到错误:\ u0041不是有效的通用字符
如果我使用wchar_t作为数据类型:
wchar_t a = '\u2639';
cout<<a<<endl;
输出为39097。
答案 0 :(得分:3)
通用字符名称(UCN)是一种向编译器传达要表示的字符的方法。只要您可以将基本源字符添加到编译器中,那么每个编译器都将看到相同的UCN,因此会看到您表示相同的字符。
这与在字面上直接写字符相反:
char a = '☹';
由于编译器只需要支持基本源字符,因此编译器甚至无法处理此代码。它实际看到的内容取决于编译器使用的源编码。一个编译器可能会在另一个编译器看到
时看到您想要的字符char a = 'Â☐¹';
但是,仅仅因为UCN能够为编译器指定字符并不意味着:
char
可以表示该字符值在您的情况下,主要问题是执行字符集是Windows的代码页(可能是CP1252)之一,它没有字符'☹'。因此,当编译器将字符“☹”转换为执行字符集时,转换会产生“?”而不是你想要的。
我的编译器的执行字符集确实包含字符'☹',但它碰巧有一个多字节表示,所以我的编译器说:
error: character too large for enclosing character literal type
char a = '☹';
^
要真正理解这个主题,您需要了解编码,字符集,它们如何进入翻译的C ++阶段,以及它与编译器处理字符和字符串文字的关系。此外,语言环境实际上与此无关; locales处理运行时行为,而您的问题完全取决于编译器编译时的编码处理。
在以下任何地方使用UTF-8的平台上:
#include <iostream>
int main() {
std::cout << "☹\n";
}
请注意,上面使用字符串文字而不是字符文字,以便字符可以扩展为其多字节表示。
不幸的是,Windows不支持这种方式的Unicode。在Windows上它更复杂:
#include <Windows.h>
#include <cwchar>
int main() {
wchar_t const *a = L"\u2639\n";
DWORD numOfCharsWritten;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), a, wcslen(a), &numOfCharsWritten, NULL);
}
不幸的是,即使上面的代码也不太可能显示您想要的内容,因为Windows上的控制台通常没有配置为能够显示Unicode字符“☹”。相反,您可能想要查看控制台使用的OEM编码(可能是CP437),查找所需字符的编码,然后打印出该值。例如,CP437的字符为“☺”,你可以像这样打印出来:
#include <iostream>
int main() {
std::cout << "\x01\n"; // ☺ has the value 0x01 in CP 437
}