我正在使用树莓派并尝试使用以下内容打印unicode字符:
TEST.CPP:
#include<iostream>
using namespace std;
int main() {
char a=L'\u1234';
cout << a << endl;
return 0;
}
当我用g ++编译时,我收到了这个警告:
test.cpp: In function "int main()":
test.cpp:4:9: warning: large integer implicitly truncated to unsigned type [-Woverflow]
输出是:
4
此外,这不在GUI中,如果这是相关的,我的发行版就会发出咆哮声。
答案 0 :(得分:4)
作为前面一个答案的参考,你不应该在Linux上使用wchar_t和w *函数。 POSIX API使用char
数据类型,大多数POSIX实现使用UTF-8作为默认编码。引用C ++标准(ISO / IEC 14882:2011)
5.3.3尺寸
sizeof(char),sizeof(signed char)和sizeof(unsigned char) 1 。 sizeof适用于任何其他基本类型(3.9.1)的结果是 实现定义。 [注意:特别是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翻译阶段
物理源文件字符是映射,在 实现定义的方式,基本源字符集 (引入行尾指标的换行符)if 必要的。
无论如何,在大多数情况下,您的源代码都没有任何转换,因此您放入char*
的字符串保持不变。如果您使用UTF-8对源代码进行编码,那么您将在char*
s中使用代表UTF-8代码单元的字节。
至于您的代码示例:它不能按预期工作,因为1 char
的大小为1个字节。 Unicode 代码点可能需要序列化多个(最多4个)UTF-8 代码单元(对于UTF-8 1 code unit == 1 byte
)。当使用UTF-8时,您可以看到here U+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;
}
在这种情况下,输出将在两条不同的行上ሴ
。
答案 1 :(得分:3)
您必须使用宽字符:
尝试:
#include<iostream>
using namespace std;
int main()
{
wchar_t a = L'\u1234';
wcout << a << endl;
}
答案 2 :(得分:2)
除非您的本机系统正在使用它,否则必须先设置本地才能使用它。
setlocale(LC_CTYPE,"");
使用wcout
代替cout
来打印搅拌器。
#include<iostream>
#include <locale>
int main()
{
setlocale(LC_CTYPE,"");
wchar_t a=L'\u1234';
std::wcout << a << std::endl;
return 0;
}