2013-08-04 144 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; 
} 

輸出將是上的兩個不同在這種情況下線。