2013-11-27 255 views
0

這聽起來像一個簡單的問題,但C++使它很難(至少對我來說):我有一個wstring,我想要第一個字母作爲wchar_t對象,然後從字符串中刪除第一個字母。C++如何獲得wstring的第一個字母

這這裏非ASCII字符不起作用:

wchar_t currentLetter = word.at(0); 

因爲它返回字符,如德語變音兩個字符(在一個循環中)。

在這裏,這是不行的,或者:

wchar_t currentLetter = word.substr(0,1); 

error: no viable conversion from 'std::basic_string<wchar_t>' to 'wchar_t' 

而且也沒有這樣的:

wchar_t currentLetter = word.substr(0,1).c_str(); 

error: cannot initialize a variable of type 'wchar_t' with an rvalue of type 'const wchar_t *' 

任何其他的想法?

乾杯,

馬丁

---- -----更新 下面是一些可執行的代碼應該說明問題。這一計劃將遍歷所有的字母和輸出一個他們一個:

#include <iostream> 
using namespace std; 

int main() { 
    wstring word = L"für"; 
    wcout << word << endl; 
    wcout << word.at(1) << " " << word[1] << " " << word.substr(1,1) << endl; 

    wchar_t currentLetter; 
    bool isLastLetter; 

    do { 
     isLastLetter = (word.length() == 1); 
     currentLetter = word.at(0); 
     wcout << L"Letter: " << currentLetter << endl; 

     word = word.substr(1, word.length()); // remove first letter 
    } while (word.length() > 0); 

    return EXIT_SUCCESS; 
} 

然而,實際的輸出我得到的是:

量F r ? ? ? Letter:f Letter:? 信,R

源文件編碼UTF8和控制檯的編碼也被設置爲UTF-8。

+1

第一個版本的問題究竟是什麼?你可以爲你的變音問題發佈代碼嗎? – nvoigt

+0

C++字符串函數本質上並不支持Unicode。不要期望他們知道變音和變音的區別。 – chris

+0

'wstring :: substr()'返回一個新的'wstring',而不是一個單獨的字符。 –

回答

1

這裏是由Sehe提供瞭解決方案:

#include <iostream> 
#include <string> 
#include <boost/regex/pending/unicode_iterator.hpp> 

using namespace std; 

template <typename C> 
std::string to_utf8(C const& in) 
{ 
    std::string result; 
    auto out = std::back_inserter(result); 
    auto utf8out = boost::utf8_output_iterator<decltype(out)>(out); 

    std::copy(begin(in), end(in), utf8out); 
    return result; 
} 

int main() { 
    wstring word = L"für"; 

    bool isLastLetter; 

    do { 
     isLastLetter = (word.length() == 1); 
     auto currentLetter = to_utf8(word.substr(0, 1)); 
     cout << "Letter: " << currentLetter << endl; 

     word = word.substr(1, word.length()); // remove first letter 
    } while (word.length() > 0); 

    return EXIT_SUCCESS; 
} 

輸出:

Letter: f 

Letter: ü 

Letter: r 

是的,你需要加速,但似乎你將需要反正外部庫。

1

C++有沒有Unicode的想法。使用一個外部庫如ICU (的UnicodeString類)或QT(QString的類),兩者都支持Unicode, 包括UTF-8。

2

由於UTF-8具有可變長度,各種索引將做在代碼單元,而不是編碼點 索引。這是不可能做到在UTF-8序列上的代碼點 隨機訪問,因爲它是 可變長度的性質。如果你想隨機訪問,你需要使用固定長度編碼,如UTF-32。爲此,您可以在字符串上使用U前綴 。

3

C++語言標準沒有明確的編碼的概念。它只有 包含一個「系統編碼」的不透明概念,wchar_t是一個「足夠大」類型的 。

要從不透明系統編碼轉換爲明確的外部編碼,您必須使用外部庫。在許多平臺上,選擇 的庫將是iconv()(來自WCHAR_T到UTF-8),它是Posix的一部分,並且 可用,儘管在Windows上,WideCharToMultibyte函數保證產生UTF8。

C++ 11以std :: string s = u8「Hello World:\ U0010FFFF」;的形式添加新的UTF8文字。那些已經在UTF8中,但他們不能通過描述的方式與不透明的wstring接口。

4 (about source files but still sorta relevant)

編碼在C++中是一個相當複雜。這是我的理解 它。

每個實現都必須支持來自基本源 字符集的字符。這些包括§2.2/ 1 (C++ 11中的§2.3/ 1)中列出的常見字符。這些字符應該都適合一個字符。在 另外實現必須支持一種方式來命名其他 字符使用一種稱爲通用字符名稱的方式,看起來像 \ uffff或\ Uffffffff,可用於引用unicode字符。它們的子集可用於標識符(列於附件E)。

這是很好的,但從文件中的字符映射到 源字符(在編譯時使用)是實現定義的。 這構成了使用的編碼。

+0

非常感謝您的幫助。不過,我更喜歡沒有依賴外部庫的解決方案。我無法想象像這樣簡單的東西不包含在C++「開箱即用」中。 – marw

+0

@marw實際上並不是那麼簡單,AFAIK(從我引用的消息來源)看,這個標準並不是很清楚。如果你想要一致性,使用一個庫。 – 2013-11-27 21:47:24

相關問題