C++ char如何区分ASCII和UNICODE?

5

我目前正在使用C++编写一个处理字母和韩文字符的程序。

然而,我了解到在C++中char的大小只有1个字节。这意味着为了处理外语字符或UNICODE,需要使用两个chars表示一个字符。

string s = string("a가b나c다");
cout<< s.length();

打印输出9

但我的问题是c ++执行如何区分两种不同类型的字符?

例如,如果我创建一个大小为9的char数组,它怎么知道是9个ASCII字符还是4个Unicode加1个ASCII?

后来我发现:

    char c;
    int a;
    char* cp = "가나다라마바사아";
    for (int i = 0; i < 20; i++) {
        c = a = cp[i];
        cout << "\n c val : " << c;
        cout << "\n a val : " << a;
    }

仅打印a的负数值。

 c val :
 a val : -80
 c val :
 a val : -95
 c val :
 a val : -77
 c val :
 a val : -86
 c val :
 a val : -76
 c val :
 a val : -39

我可以推断出,对于非ASCII字符,它只使用负值?但这不是很浪费吗?

我的问题简而言之:C++是否仅通过查看字符是否为负数来区分ASCII字符和Unicode字符?


简而言之的答案:解析器通过查找字符的前几位来决定是否将1〜4个字符视为1个字形,因此在某种程度上,我的假设是正确的。


ASCII是Unicode的子集,不存在“区分”的情况。 - M.M
1个回答

8

C++执行如何区分两种不同类型的字符?

它并不能。编译器在编译时决定将您的字符串编码为Unicode。在这种情况下,它似乎选择了UTF-8。

它如何知道是9个ASCII字符还是4个Unicode和1个ASCII字符?

同样地,它并不能。您的字符串包含9个char值(不包括任何终止字符)。表示的实际“字符”(或“字形”)数量只能通过解析字符串来确定。如果您知道它是UTF-8,则相应地解析。

我可以推断出对于非ASCII字符,它只使用负值吗?但这不是很浪费吗?

不是。嗯,有点。如果您感兴趣,请阅读一份关于Unicode(特别是UTF-8)的入门指南。您可以阅读实际的标准,但它非常庞大。Wikipedia应该足以更好地理解。

您会发现多字节字符串具有高位设置。这使得正确解析多字节值成为可能。这并不是真正的浪费,因为标准安排了更宽的编码通常保留用于较不常见的值。
输出负数的原因是您正在使用带符号的 char 类型。如果强制转换为 unsigned,您将看到这些值仅仅大于 127。当您阅读更多关于 UTF-8 如何编码的内容时,您就会明白其中的原因。
总之,我的回答是:c++ 并不是只通过检查字符是否为负来区分 ascii 字符和 unicode 字符。"负数"是一种数字系统。您可能习惯于使用二进制补码。编码或不编码:没有“负数”。

我所说的“负数”是指它是否只使用可用值的一半。那么,您的意思是当两个字符相加等于一个字符时,这两个字符总是大于127吗? - NamHo Lee
我已经编辑了一些内容,还提供了一个链接,你可以阅读关于UTF-8的相关信息。其中有关于该标准要求与ASCII向后兼容的解释。 - paddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接