gpt4 book ai didi

c++ - 使用 '\uxxxx' 格式定义的字符显示错误的字符

转载 作者:太空狗 更新时间:2023-10-29 21:24:39 26 4
gpt4 key购买 nike

我正在使用 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。

最佳答案

通用字符名称 (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";
}

请注意,上面使用的是字符串文字而不是字 rune 字,因此字符可以扩展为其多字节表示。

不幸的是,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
}

关于c++ - 使用 '\uxxxx' 格式定义的字符显示错误的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15558977/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com