作为参考以前的答案之一,你不应该在Linux上使用的wchar_t和W *功能。 POSIX API使用数据类型char
,大多数POSIX实现使用UTF-8作为默认编码。引用C++标准(ISO/IEC 14882:2011)
5.3.3的sizeof
的sizeof(char)的,的sizeof(符号字符)和sizeof(无符号字符)是。 适用于任何其他基本类型(3.9.1)的sizeof的结果是实现定义的 。 [注意:sizeof(bool), sizeof(char16_t),sizeof(char32_t)和sizeof(wchar_t)是 实现定义的。 74 - 注完]
UTF-8使用1字节的代码,以及最多4个编码单元来表示代码点,所以char
足以存储UTF-8串,但操纵他们,你会需要找出一个特定的代码单元是否由多个字节表示,并且考虑到这一点,构建您的处理逻辑。 wchar_t
具有实现定义的大小,我所看到的Linux发行版的这种数据类型的大小为4个字节。
有从源代码到目标代码的映射可以改变你的编码在一个特定的编译器的方法的另一个问题:
2。2个阶段翻译的
物理源文件中的字符是映射,在一个 实现定义的方式,基本源字符集 (引入终了行指标新行字符)如果需要 。
无论如何,在大多数情况下,您的源代码没有任何转换,因此您放入char*
的字符串保持不变。如果你用UTF-8编码你的源代码,那么你将在你的char*
s中有代表UTF-8代码单元的字节。
至于你的代码示例:它没有按预期工作,因为1 char
的大小为1个字节。 Unicode 代码点可能需要串行化(对于UTF-8 1 code unit == 1 byte
)几个(最多4个)UTF-8 代码单元。当使用UTF-8时,您可以看到hereU+1234
需要三个字节E1 88 B4
,因此不能存储在单个字符中。如果您修改代码如下它会就好了工作:
#include <iostream>
int main() {
char* str = "\u1234";
std::cout << str << std::endl;
return 0;
}
这将输出ሴ
虽然你可能没有什么根据您的控制台和安装的字体上看到,实际字节去那里。请注意,使用双引号,您在内存中也有一个\0
终止符。
你也可以使用一个数组,而不是单引号,因为你需要一个不同的数据类型(参见here了解更多信息):
#include <iostream>
int main() {
char* str = "\u1234";
std::cout << str << std::endl;
// size of the array is 4 because \0 is appended
// for string literals and there are 3 bytes
// needed to represent the code point
char arr[4] = "\u1234";
std::cout.write(arr, 3);
std::cout << std::endl;
return 0;
}
输出将是ሴ
上的两个不同在这种情况下线。
不行,'a'必须是宽字符。 –
@BasileStarynkevitch,恩,是的,我错过了改变这一点。修复。 – Devolus
非常感谢你,这个解决方案完美地工作:) – lkjhgfdsa