2012-12-13 40 views
4

當我在C++中嘗試使用非英語字符的tolower()時,它不能正常工作。我搜索了這個問題,並且遇到了有關語言環境的問題,但我不確定最佳解決方案。tolower()不適用於C++中的Ü,Ö

我的示例代碼如下:

printf("%c ",tolower('Ü')); 
+0

在Bart van Ingen Schenau的回答中提到,但值得強調的是:*字符通常不能被認爲具有較低/大寫變體*。閱讀[letter case](http://en.wikipedia.org/wiki/Letter_case)。 – unwind

回答

6

不幸的是,C++標準庫沒有改變的所有可能的非英文字符的情況下足夠的支持(只限於那些有字符變體情況下完全)。這種限制是由於C++標準假設單個字符及其變體形式恰好佔據一個對象(或用於寬字符的wchar_t對象)以及非英文字符不能保證爲真(也取決於字符如何編碼)。

如果您的環境使用單字節編碼相關的字符,這可能會給你想要的東西:

std::cout << std::tolower('Ü', locale()); 

隨着寬字符,你將可能有更多的運氣:

std::wcout << std::tolower(L'Ü', locale()); 

,但即使如此也不會給出toupper(L'ß')的正確結果,這將是兩個字符的序列L"SS")。

如果你需要的所有字符支持,看看the ICU library,尤其the part about case mappings

+0

該解決方案僅適用於Windows還是適用於Ubuntu?因爲我嘗試了他們,但代碼不工作。 – Yavuz

+0

@Yavuz:它也應該在Ubuntu上工作,但它可能取決於您的區域設置。請參閱Konrad Rudolph的答案,瞭解如何輕鬆使用非默認語言環境。 –

+0

我同意這裏所說的減去'ß'轉換。該標準說,這應該*不*轉換爲「SS」或「ẞ」:http://stackoverflow.com/a/37571371/2642059 –

3

像巴特曾表示,C++根本不喜歡多字節編碼。幸運的是,您可以使用Boost.Local解決這個問題,而不會有太多麻煩。這裏有一個簡單的例子:

#include <iostream> 
#include <locale> 
#include <boost/locale.hpp> 

int main() { 
    boost::locale::generator gen; 
    std::locale loc = gen("en_US.UTF-8"); 
    std::string line; 
    while (std::getline(std::cin, line)) 
     std::cout << boost::locale::to_lower(line, loc) << '\n'; 
} 

進行編譯,我們需要鏈接到Boost.Locale庫:

g++ -lboost_locale lower.cpp -o lower 

當我們執行它,我們得到如下:

$ ./main <<< 'ICH HÄTTE GERNE EINEN SÜßEN HASEN' 
ich hätte gerne einen süßen hasen 
相關問題