如何在 Turbo C++ 中使用 Unicode?

How can I use Unicode in Turbo C++?

如何在 Turbo C++ 中使用 Unicode 符号?

我特别想要上下标符号。

我必须使用过时的 Turbo C++,因为这是我的学校提供​​的,我必须将其用于我的项目。

如前所述,Turbo C++ 不会让您直接访问 Unicode。它可能太旧了,甚至无法生成可以使用系统库 (DLL) 的代码,因此 - 即使通过手动重新创建头文件,您也无法调用 wprintf 这可能即使在神秘的 cmd 终端上也能输出正确的 Unicode 微软 Windows 直到今天。

但是,cmd 终端中使用的默认字符编码支持一些非 ASCII 字符 - 这完全取决于您 OS 的语言(区域设置)配置。 (例如,对于西欧语言,如果您的 Windows 是英语,则通常是 "cp-852" - although it can be CP 850

None 这些遗留 8 位字符映射编码将包括所有十位数字作为上标 - 但您可能有一些可用(例如,CP 850 功能“¹,²,³”) .

因此,您可以查看终端代码页,并在维基百科上查看它们的代码 - 您可以在 Windows 终端中使用 chcp 命令检查和更改当前代码页。如果您的 Windows 版本支持 UTF-8,它涵盖了所有可打印的 Unicode 字符,您必须在终端中输入 chcp 65001。 (我不知道哪个 Windows 版本支持它,也不知道你使用的是哪个版本。)

一旦你设法做到这一点,你所需要的就是打印 UTF-8 中上标数字的字节序列,使用字符串中字符的“\xHH”编码(我不确定如果 Turbo C++ 允许它。否则,`printf ("%c%c", 0xHH, 0xHH) 将起作用。)

为方便起见,我附上了上标的代码点和 UTF-8 编码:

0x00B2: SUPERSCRIPT TWO - ² - utf-8 seq: b'\xc2\xb2'
0x00B3: SUPERSCRIPT THREE - ³ - utf-8 seq: b'\xc2\xb3'
0x00B9: SUPERSCRIPT ONE - ¹ - utf-8 seq: b'\xc2\xb9'
0x0670: ARABIC LETTER SUPERSCRIPT ALEF - ٰ - utf-8 seq: b'\xd9\xb0'
0x0711: SYRIAC LETTER SUPERSCRIPT ALAPH - ܑ - utf-8 seq: b'\xdc\x91'
0x2070: SUPERSCRIPT ZERO - ⁰ - utf-8 seq: b'\xe2\x81\xb0'
0x2071: SUPERSCRIPT LATIN SMALL LETTER I - ⁱ - utf-8 seq: b'\xe2\x81\xb1'
0x2074: SUPERSCRIPT FOUR - ⁴ - utf-8 seq: b'\xe2\x81\xb4'
0x2075: SUPERSCRIPT FIVE - ⁵ - utf-8 seq: b'\xe2\x81\xb5'
0x2076: SUPERSCRIPT SIX - ⁶ - utf-8 seq: b'\xe2\x81\xb6'
0x2077: SUPERSCRIPT SEVEN - ⁷ - utf-8 seq: b'\xe2\x81\xb7'
0x2078: SUPERSCRIPT EIGHT - ⁸ - utf-8 seq: b'\xe2\x81\xb8'
0x2079: SUPERSCRIPT NINE - ⁹ - utf-8 seq: b'\xe2\x81\xb9'
0x207A: SUPERSCRIPT PLUS SIGN - ⁺ - utf-8 seq: b'\xe2\x81\xba'
0x207B: SUPERSCRIPT MINUS - ⁻ - utf-8 seq: b'\xe2\x81\xbb'
0x207C: SUPERSCRIPT EQUALS SIGN - ⁼ - utf-8 seq: b'\xe2\x81\xbc'
0x207D: SUPERSCRIPT LEFT PARENTHESIS - ⁽ - utf-8 seq: b'\xe2\x81\xbd'
0x207E: SUPERSCRIPT RIGHT PARENTHESIS - ⁾ - utf-8 seq: b'\xe2\x81\xbe'
0x207F: SUPERSCRIPT LATIN SMALL LETTER N - ⁿ - utf-8 seq: b'\xe2\x81\xbf'
0xFC5B: ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM - ﱛ - utf-8 seq: b'\xef\xb1\x9b'
0xFC5C: ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM - ﱜ - utf-8 seq: b'\xef\xb1\x9c'
0xFC5D: ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM - ﱝ - utf-8 seq: b'\xef\xb1\x9d'
0xFC63: ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM - ﱣ - utf-8 seq: b'\xef\xb1\xa3'
0xFC90: ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM - ﲐ - utf-8 seq: b'\xef\xb2\x90'
0xFCD9: ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM - ﳙ - utf-8 seq: b'\xef\xb3\x99'

(这是在交互模式下使用以下 Python 片段生成的:)

import unicodedata
for i in range(0, 0x10ffff):
    char = chr(i)
    try:
        name = unicodedata.name(char)
    except ValueError:
        pass
    if "SUPERSCRIPT" not in name:
        continue
    print(f"0x{i:04X}: {name} - {char} - utf-8 seq: {char.encode('utf-8')}")

Turbo C++(不是 BDS2006 Turbo C++)用于 MS-DOS 16 位目标,所以它根本不支持 Unicode,也不支持 TTF 字体等。所以为了让 Unicode 工作,你有两个选择:

  1. 自己实现 Unicode

    因此您需要呈现 Unicode 文本。在图形模式下很简单。只需使用“完整”的 Unicode 字体,例如:

    IIRC 它是光栅的,因此很容易解码和渲染(您甚至可以在较新的 OS 中从中创建一个大位图,并在 MS-DOS 中将其用作字体)。对于图形模式下的渲染,您可以使用直接像素访问 (VGA/VESA)。在文本模式下,这要困难得多,因为您需要用您实际使用的字符更新 EGA/VGA 字体。但是屏幕上实际呈现的不同字符的数量限制为每种字体 256 个。欲了解更多信息,请参阅:

    • Graphics rendering in C++

    当然,在 MS-D 下支持整个 Unicode 是一个问题OS,因为即使在小分辨率下,完整字体通常也有 12-64 MB 大,因此您需要有足够的 XMS 内存(因为你不再适合 640 KB 或 1 MB 模型)并实现快速 paging/access 以使用字符以便快速可用...另一种选择是使用 32 位保护模式,你可以获得 32 位线性内存访问(但是你没有更多的 MS-DOS 支持并且需要自己做所有 OS 的事情,但是像 D[=59 这样的扩展器=]4GW 可以为您做一些...)

    您可以使用一种快捷方式来避免内存管理。您可以创建一个 RAM disk 并将您的原始字体图像作为文件存储在 RAM 磁盘中。对它的文件访问应该很快(比访问 HDD 快得多)...所以在应用程序开始时,将字体从 HDD 复制到 RAM 磁盘位置,然后只使用它...因此,不需要 XMS没有了。

  2. 将 Unicode 字符串转换为扩展 ASCII

    使用支持标准 ASCII 之外的特殊字符的字符 table。有 MS-DOS 实用程序(支持 latin1、2、kamenicky 等)提供扩展字体和键盘处理(在选定的代码页内)。

    因此,您需要对要支持的所有字符进行转换 table,并在 UTF-8、UTF-16 和 ASCII + 扩展字符之间进行映射。但是,这样它只能支持128个扩展字符。