2013-08-04 88 views
0

我使用的是树莓派,并试图用这样的打印Unicode字符:打印Unicode字符Linux编程

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和我的分布是raspbian wheezy,如果这是相关的。

回答

2

除非您的本机系统正在使用它,否则您必须先设置本地才能使用它。

setlocale(LC_CTYPE,""); 

要打印stirng使用wcout代替cout

#include<iostream> 
#include <locale> 

int main() 
{ 
    setlocale(LC_CTYPE,""); 
    wchar_t a=L'\u1234'; 
    std::wcout << a << std::endl; 
    return 0; 
} 
+0

不行,'a'必须是宽字符。 –

+0

@BasileStarynkevitch,恩,是的,我错过了改变这一点。修复。 – Devolus

+0

非常感谢你,这个解决方案完美地工作:) – lkjhgfdsa

3

你必须使用宽字符:

尝试:

#include<iostream> 
using namespace std; 

int main() 
{ 
    wchar_t a = L'\u1234'; 
    wcout << a << endl; 
} 
+1

为什么我们必须使用宽字符? – 0x499602D2

+0

@ dieram3,不,你不应该。首先,wchar_t与Unicode没有任何关系 - 仅仅在大多数Linux发行版上存储一个4字节的代码单元就足够了,否则就是实现定义的。 POSIX API使用每个代码点编码(如UTF-8)的单字节,因此您需要使用普通的'char'数据类型。 wchar_t与Unicode一起使用的用法来自Windows –

+0

@ 0x499602D2 我宁可建议不要在Linux上使用宽字符,请看看我的答案:https://stackoverflow.com/questions/18040393/printing-unicode-字符-C-LINUX/32413257#32413257 –

4

作为参考以前的答案之一,你不应该在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; 
} 

输出将是上的两个不同在这种情况下线。