2015-10-16 201 views
2

我有一個關於字符串文字如何存儲在內存中的C++的問題。我知道char是按照他們的ASCII碼存儲的,但我寧願在Unicode字符集之後。原因是我試圖處理一些地區。讓我們假設我想要做的是將小寫字符轉換爲大寫字母。這個工程在Xcode終端,如何將字符串文字存儲在內存中的c + +?

#include <iostream> 
#include <string> 
#include <cctype> 
#include <clocale> 

using namespace std; 

int main() 
{ 
wcout.imbue(std::locale("sv_SE.Utf-8")); 
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale("sv_SE.Utf-8")); 

wstring str {L"åäö"}; // Swedish letters 

f.toupper(&str[0], &str[0] + str.size()); 

std::wcout << str.length() << std::endl; 
std::wcout << str << std::endl; 
} 

Output: 
3 
ÅÄÖ 

然而,當我嘗試在OS X終端,我得到垃圾運行它,

Output: 
3 
ÅÄÖ 

此外,當我提示輸入而不是用戶,

#include <iostream> 
#include <string> 
#include <cctype> 
#include <clocale> 

using namespace std; 

int main() 
{ 
wcin.imbue(std::locale("")); 
wcout.imbue(std::locale("sv_SE.Utf-8")); 
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale("sv_SE.Utf-8")); 

//wstring str {L"åäö"}; 
wcout << "Write something>> "; 
wstring str; 
getline(wcin, str); 

f.toupper(&str[0], &str[0] + str.size()); 

std::wcout << str.length() << std::endl; 
std::wcout << str << std::endl; 
} 

我收到的垃圾從Xcode的終端,

Output: 
Write something>> åäö 
6 
åäö 

而當我使用這些字母時,OS X termial實際掛起。它是可以修改wcin流假定爲C編碼wcin.imbue(std::locale());,這仍然給在Xcode相同的輸出,但在OS X終端給出如下:

Output: 
Write something>> åäö 
3 
ŒŠš 

所以問題很明顯地與編碼。所以我想知道如何將字符串文字實際存儲在C++的內存中。這可以分成兩種不同的情況。

案例1:在源代碼中鍵入的字符串文字,例如wstring str {L"åäö"};

案例2:通過標準輸入流輸入的字符串(在這種情況下爲wcin)。

這兩種情況不一定以相同的方式存儲字符串。我知道unicode是一個字符集,utf-8是一種編碼,所以我更想知道的是,如果字符串文字在存儲在內存中時編碼,那麼情況如何。此外,如果有人知道如何以自動的方式識別當前終端中使用的編碼,那將是非常好的。

BR 帕特里克

編輯

我得到一些註釋的,儘管他們中的一些是好的,是不完全相關的問題。這意味着這個問題可能需要一些澄清。這個問題可以看作是對病態公式的概括:

「我可以假定字符串文字與他們的unicode點代碼一起存儲在內存中嗎?」

這個問題至少有兩個原因。首先它假定字符串文字是如何存儲的(使用unicode代碼點)。這意味着答案必須與unicode相關,儘管這種關係可能完全沒有意義。此外,這個問題是一個是或者否的問題,如果答案是否定的,這個問題將不會起作用。

我也明白這可以通過測試將代碼點轉換爲其整數等值並打印出來,但這需要我測試它對整個unicode字符集(這似乎是一種不合理的方式)。

+2

它使用'utf8',你應該使用'string','cout'等而不是'w''等價。 –

+0

@ el.pescado這就是我讀過的。問題在於字母「åäö」不適合單個字符。這給了我不正確的字符串長度。你的意思是我應該將這些問題分解爲兩個並分別處理它們?進一步的原因是什麼這是合適的? – patrik

+2

「問題在於'åäö'不適合單個字符」 - 這就是utf8編碼的要點 - 將這些字母合併到多個字符中。最好將'length()'作爲「字節數」來處理,因爲它無論如何都是中斷的。請參閱http://utf8everywhere.org/和http://programmers.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful –

回答

1

首先將文件解釋爲一系列字符的方式是實現定義的。您必須查閱您的編譯器文檔以確定這一點。

其次使用的字符集也是實現定義的。所以你必須再次諮詢你的編譯器。

當您插入非ASCII字符(可能也使用ascii)時,可能發生的情況是編譯器會以不同的方式解釋它們。您必須檢查不同的編譯器實際上是否可以處理相同的編碼,最可能使用的源編碼是UTF-8。

此外,也許你會更好地使用UTF-8編碼文本的大部分程序(只有靠近API,需要wchar_t需要這樣處理字符串)。

底線。確保您的編譯器逐字地存儲字符串字面值並使用普通(窄)字符串,並使用以UTF-8編碼保存的編輯器。

相關問題