3

我正在使用 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 字符(它是一个类似于 ∥ 的符号,但有多个符号看起来像这样,我不知道它是哪个)。

在 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。

4

1 回答 1

3

通用字符名称 (UCN) 是一种向编译器传达您想要表示的字符的方法。只要您可以将基本源字符提供给编译器,那么每个编译器都会看到相同的 UCN,因此会看到您代表的是相同的字符。

这与在源代码中逐字写入字符相反:

char a = '☹';

由于编译器只需要支持基本的源字符,因此编译器甚至可能无法处理此代码。它实际看到的内容取决于编译器使用的源编码。一个编译器可能会看到您想要的字符,而另一个编译器会看到

char a = 'Â☐¹';

但是,仅仅因为 UCN 能够向编译器指定字符并不意味着:

  • 编译器的执行字符集包含该字符或
  • 数据类型char可以表示该字符值

在您的情况下,主要问题是执行字符集是 Windows 的代码页之一(可能是 CP1252),它没有字符“☹”。所以当编译器将字符'☹'转换为执行字符集时,转换产生'?' 而不是你想要的。

我的编译器的执行字符集确实包含字符“☹”,但它恰好有一个多字节表示,所以我的编译器说:

error: character too large for enclosing character literal type
    char a = '☹';
             ^

要真正理解这个主题,您需要了解编码、字符集、它们如何在 C++ 翻译阶段发挥作用,以及它们与编译器对字符和字符串文字的处理有何关系。此外,语言环境实际上与这些无关。语言环境处理运行时行为,而您的问题完全在于编译器对编码的编译时处理。


在到处使用 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
}
于 2013-03-22T21:34:20.837 回答