【发布时间】:2016-07-08 16:59:14
【问题描述】:
我对 C++ 字符串中的 unicode 字符感到困惑。
我有一个这样的程序:
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "3rd char of " << argv[1] << "is: " << argv[1][2] << std::endl;
}
当我用这个命令运行它时:
mapper abͲ
它返回这个:
3rd character of abͲis: �
现在,显然我的系统支持 unicode (Ubuntu 16.04),编译器不介意程序 (g++ 5.3.1)。我知道 argv 是 char* 对象的向量,但是如果字符是 unicode,我如何访问单个参数向量中的单个字符?一定是我遗漏了一些类型冲突。
【问题讨论】:
-
您必须了解 UTF-8 的工作原理。
-
@LarryTurtis - 建议:尝试 cout
strlen(argv[1])、int(argv[1][2])和int(argv[1][3]) -
你不能只输出
char*字符串的单个字节而不了解字节是如何编码的。在此示例中,输入字符Ͳ实际上是 Unicode 代码点U+0372 GREEK CAPITAL LETTER ARCHAIC SAMPI,它以 UTF-8 编码为两个字节0xCD 0xB2,它们是 UTF-8 编码的char*字符串中的单独char元素。 -
解决这些编程问题的一种方法是将输入字符串转换为 UTF-32,即每个字符的固定长度(= 1 int = 4 字节),然后使用它们,或者其他方法是使用一些像
ICU这样的UTF库,它的API函数可以选择特定的字符、字符串的长度(实际上是字符数)等等。出于教育目的,你尝试自己处理UTF-8很好,但是@ 987654334@ 本身现在已经超过 25 年了,它仍在修复和开发中...... ;) -
现在您可能会感到困惑,为什么 UTF-8 被多次选择作为 linux 的默认值,而它远非微不足道,并且具有每个字符的可变字节数功能。答:大多数情况下,处理 ASCII 字符串(主要是文件名)的旧命令行工具无需修改即可处理 UTF-8 文件名,而不会意识到字符串是 UTF-8 编码的。对于 UTF-16/UCS-2(Java、Win32)编码,情况并非如此,需要更改和重新编译所有工具才能准备好 UTF-16/UCS-2。