【问题标题】:C read and write unsigned char (0 - 255) as UTF-8C 读写 unsigned char (0 - 255) 为 UTF-8
【发布时间】:2020-09-30 21:51:17
【问题描述】:

我正在尝试在 C 中从 Windows 下的控制台读取和写入 unsigned char (0 - 255) 扩展 ASCII 字符 (unicode)。

在扩展 ASCII(unicode)下,代码点 255 是 ÿ,代码点 220 是 Ü

现在我有以下代码用于编写和阅读。

#include<stdio.h>
#include<locale.h>

int main() {
    setlocale(LC_ALL, "");

    unsigned char ch = 255;
    wprintf(L"Character %d = %lc\n", ch, ch);

    wprintf(L"Enter a character: ");
    wscanf(L"%lc", &ch);
    wprintf(L"Character %d = %lc\n", ch, ch);

    return 0;
}

输出是:

Character 255 = ÿ
Enter a character: ÿ
Character 220 = Ü

显然,代码点 255 正确显示为 ÿ。 但是,当以 ÿ 作为输入时,它被读取为代码点 220。 因此,当打印代码点 220 时,它会显示为 Ü

因此,写作工作正常。但是,在读取时,当 ASCII 字符大于 127 (128 - 255) 时,读取的 code-point 比实际值小 36。

请您帮助我了解我做错了什么以及如何解决这个问题。

【问题讨论】:

  • 扩展 ascii != utf-8
  • @para 也许我的措辞有误。我已将术语从 UTF-8 更改为 Unicode。我的意思是我需要在 unsigned char 中使用 Unicode 的前 256 个(0 - 255)个字符并从控制台读取它并打印回控制台。
  • 您的控制台使用什么编码?哪个操作系统?
  • wscanf%lcunsigned char 可能会导致未定义的行为。
  • @MarkRansom 我正在使用带有 DOS 终端的 Windows。终端编码为CP437。

标签: c unicode utf-8 ascii extended-ascii


【解决方案1】:

%lc 采用wide character wchar_t,宽是指它是多字节的,但确切的大小是特定于实现的。给它一个 1 字节 unsigned char 会导致奇怪的行为,因为它会额外读取一两个字节。

但如果您使用 1 字节字符,则不需要使用 wprintf 或 wscanf。只需使用printfscanf

而且,正如其他人所指出的,“扩展 ASCII”不是“Unicode”。 See this question for more.

【讨论】:

  • 我尝试过使用 printf 和 scanf。但是,它会产生相同的结果。基本上在读取时,它读取为 CP437(这是终端编码)。但是我们需要使用 unicode 来代替。我所说的 unicode 的意思是我需要处理 unicode 的前 256 个字符。
  • @PratanuMandal 哪种 Unicode 编码? UTF-8? UTF-16?或者你的意思是前 256 个代码点到 U+00FF?我不是说钝,字符编码很复杂。
  • @PratanuMandal 好的,你想用它们做什么?到目前为止,您只是在读取一个字符并将其打印出来。
  • 我读取了字符(介于 0 到 255 之间),并将其存储。然后可能会根据某些条件对该值进行操作(加法或减法)。操作完成后,将最终结果打印回给用户。
  • 您需要将平台编码中的字节转换为 Unicode 代码点。如果您的平台编码是 CP437,则不能保证单个字节 CP437 可以表示为一个字节作为 Unicode 代码点。也就是说,代码点可能是 > 255 的数字。事实上,某些 CP437 字符确实映射到代码点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
相关资源
最近更新 更多