gpt4 book ai didi

c - 如果有的话,编码在什么时候开始在 C 中发挥作用?那么如何正确打印字符串呢?

转载 作者:行者123 更新时间:2023-11-30 14:37:42 26 4
gpt4 key购买 nike

为了研究 C 如何处理 UTF-8/Unicode 字符,我做了这个小实验。

这并不是说我现在正在尝试解决任何特定的问题,但我知道 Java 以对编码器透明的方式处理整个编码情况,我想知道 C 的级别要低得多,对待它的角色。

以下测试似乎表明 C 完全不了解编码问题,因为显示设备只需要知道在屏幕上显示字符时如何解释字符序列。后来的测试(当打印 _ 包围的字符时)似乎特别有说服力?

#include <stdio.h>
#include <string.h>

int main() {
char str[] = "João"; // ã does not belong to the standard
// (or extended) ASCII characters

printf("number of chars = %d\n", (int)strlen(str)); // 5

int len = 0;
while (str[len] != '\0')
len++;
printf("number of bytes = %d\n", len); // 5

for (int i = 0; i < len; i++)
printf("%c", str[i]);
puts("");
// "João"

for (int i = 0; i < len; i++)
printf("_%c_", str[i]);
puts("");
// _J__o__�__�__o_ -> wow!!!

str[2] = 'X'; // let's change this special character
// and see what happens
for (int i = 0; i < len; i++)
printf("%c", str[i]);
puts("");
// JoX�o

for (int i = 0; i < len; i++)
printf("_%c_", str[i]);
puts("");
// _J__o__X__�__o_
}

我了解 ASCII/UTF-8 的工作原理,但我真正不确定的是这些字符在什么时候被解释为“复合”字符,因为 C 似乎只是将它们视为哑字节。这背后的真正科学原理是什么?

最佳答案

打印不是 C 的函数,而是显示上下文的函数,无论它是什么。对于终端,有 UTF-8 解码功能,可将原始字符数据映射为使用特定字体在屏幕上显示的字符。图形应用程序中也存在类似的显示逻辑,但与比例字体宽度、连字、连字符和许多其他打印问题相关的复杂性更高。

在内部,这通常是通过首先将 UTF-8 解码为某种中间形式来完成的,例如 UTF-16 或 UTF-32,以用于查找目的。简而言之,字体中的每个字符都有一个 Unicode 标识符。实际上,这要复杂得多,因为存在字符变体的空间,并且多个字符可以由字体中的单个字符表示,例如“fi”和“ff”ligatures 。正如 Unicode 所允许的,像“ç”这样的重音字符可以是字符的组合。这就是类似 Zalgo text 的地方来吧:您经常可以将数量确实荒谬的 Unicode“组合字符”堆叠在一起形成单个输出字符。

版式是一个复杂的世界,需要复杂的库才能正确渲染。

您可以用 C 语言处理 UTF-8 数据,但只能使用特殊的库。 C 标准库中附带的任何内容都无法理解它们,对于 C 来说,它只是一系列字节,并且就长度而言,它假设字节等同于字符。这就是 strlen ,这样的工作以字节为单位,而不是字符。

例如,C++ 对字节和字符之间的区别提供了更好的支持。其他语言有更好的支持,像 Swift 这样的语言特别支持 UTF-8,一般支持 Unicode。

关于c - 如果有的话,编码在什么时候开始在 C 中发挥作用?那么如何正确打印字符串呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57066709/

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