2013-08-01 61 views
16

如何在C或C++中將多語言字符串或unicode字符串轉換爲大寫/小寫字符串。將C++中的unicode字符串轉換爲大寫

+0

檢查此線程的http://計算器的.com /問題/ 1614595 /轉換-寬炭字符串到小寫式-C。它可能會幫助你。 – AnkitJain

+2

「Unicode」是什麼意思? Unicode標準定義了許多不同的編碼 - 您使用哪一種編碼? UTF-8? UTF-16? UTF-32? –

+0

這裏 – Backtrack

回答

1

您可以通過wstring迭代,並使用towupper/towlower

for (wstring::iterator it = a.begin(); it != a.end(); ++it) 
     *it = towupper(*it); 
3

有了相當多的困難,如果你打算做是正確的。

通常的用例是用於比較目的,但問題比這個更普遍。

有一個從C++馬特Austern here(PDF)大約2000年的報告

+2

不區分大小寫的比較的上限只是錯誤的方法。正確的做法是擺脫*只是*的情況下差異(有一種操作稱爲「casefolding」,可用於此),然後比較。 Uppercasing沒有擺脫*只有*的情況下的差異。 –

+0

我甚至不同意這種說法。你想擺脫與比較無關的所有差異。當然,'Æ=æ',但這可能等於AE,ae和AE。 – MSalters

+0

這不是一個答案 – Purefan

0

對於C在當前線程調整的C語言環境後,我會用toupper一個相當詳細的文件。

setlocale(LC_CTYPE, "en_US.UTF8"); 

對於C++我會使用的std::ctype<char>toupper方法:

std::locale loc; 

auto& f = std::use_facet<std::ctype<char>>(loc); 

char str[80] = "Hello World"; 

f.toupper(str, str+strlen(str)); 
+0

我的代碼是: - 的setlocale(LC_CTYPE, 「en_US.UTF8」); std :: locale loc; 自動&F =的std :: use_facet <性病:: CTYPE >(LOC); char str [80] =「pièces」; (str,str + strlen(str)); cout << str; 但我得到的輸出 - 片 – Pankaj

+1

@Pankaj那是因爲en_US環境沒有任何東西,是不是在A-Z的大寫形式。 –

+0

@ R.MartinhoFernandes所以我必須這樣做,實際上我對CPP非常陌生,我甚至不知道CPP中的hello world program。 一些如何管理.. – Pankaj

2

設置locale first,例如:

setlocale(LC_ALL, "German")); /*This won't work as per comments below */ 

setlocale(LC_ALL, "English")); 

setlocale(LC_MONETARY, "French"); 

setlocale(LC_ALL, ""); //default locale 

然後使用

std::use_facetstd::locale如下: -

typedef std::string::value_type char_t; 
char_t upcase(char_t ch) 
{ 
return std::use_facet< std::ctype<char_t> >(std::locale()).toupper(ch); 
} 

std::string toupper(const std::string &src) 
{ 
std::string result; 
std::transform(src.begin(), src.end(), std::back_inserter(result), upcase); 
return result; 
} 

const std::string src = "Hello World!"; 
std::cout << toupper(src); 
+4

搞笑的是你提到的德國區域,然後繼續使用,不會對適當德國uppercasing工作的方法,因爲它採用的是1對1的地圖('transform'),但在兩個字符uppercasingß結果。 –

+0

@ R.MartinhoFernandes,啊,IDK:d更新,謝謝 – P0W

+0

其實我想法文文本轉換,所以我使用的setlocale (LC_MONETARY, 「法國」); 但是,當我將chloë轉換爲大寫字符時,將CHLOë作爲輸出。 – Pankaj

9

如果您的系統已經是UTF-8,使用std::use_facet,你可以寫:

#include <iostream> 
#include <locale.h> 

int main() { 
    std::locale::global(std::locale("")); // (*) 
    std::wcout.imbue(std::locale()); 
    auto& f = std::use_facet<std::ctype<wchar_t>>(std::locale()); 

    std::wstring str = L"Zoë Saldaña played in La maldición del padre Cardona."; 

    f.toupper(&str[0], &str[0] + str.size()); 
    std::wcout << str << std::endl; 

    return 0; 
} 

,你會得到(http://ideone.com/AFHoHC):

佐伊·索爾達娜扮演LA MALDICIÓNDEL PADRE CARDONA。

如果不工作,你將不得不改變(*)std::locale::global(std::locale("en_US.UTF8"));或者你確實對。平臺的UTF-8語言環境。

+0

。 。這是一個很好的C++解決方案,但是C++解決方案本身並不重要。 – rubenvb

+0

@rubenvb:是的,當然你需要檢查UTF-8語言環境是否存在,實際上不會有'std :: locale :: global std :: locale ::「global」(std :: locale(「en_US.UTF-8」)); Apple的std :: locale(「」))'做這項工作嗎? –

+0

@Kyle_the_hacker LLVM 4.2編譯器,但不在LLVM GCC 4.2編譯器上。 我認爲'auto'不受支持在LLVM GCC中。 – Pankaj

4

我發現problem_

1. 的setlocale的2溶液(LC_CTYPE 「的en_US.UTF-8」); //語言環境將是UTF-8已啓用英語

std::wstring str = L"Zoë Saldaña played in La maldición del padre Cardona.ëèñ"; 

std::wcout << str << std::endl; 

for (wstring::iterator it = str.begin(); it != str.end(); ++it) 
    *it = towupper(*it); 

std::wcout << "toUpper_onGCC_LLVM_1 :: "<< str << std::endl; 

這是關於LLVM GCC 4.2編譯器的工作。

2. std :: locale :: global(std :: locale(「en_US.UTF-8」)); //語言環境將啓用UTF-8英語

std::wcout.imbue(std::locale()); 
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale()); 

std::wstring str = L"Chloëè";//"Zoë Saldaña played in La maldición del padre Cardona."; 

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

std::wcout << str << std::endl; 

這是Apple LLVM 4.2中的工作。

這兩種情況下,我跑在Xocde上。 但我找到一種方法來在Eclipse中使用g ++編譯器運行此代碼。

+2

你讀過其他答案嗎?你基本上覆制/粘貼@ mewa's和我的答案...... –

2

在Windows中,對於語言環境未知的混合語言應用程序,請考慮CharUpperBuffWCharLowerBuffW。這些函數處理toupper()沒有的變音符號。

+0

使用特定於平臺的函數來操作文本只有不足之處 - 它將你的代碼綁定到該平臺,對你沒有任何好處。考慮到有許多不是特定於平臺的良好文本操作庫,你只是通過這樣做而傷害自己。 – Clearer

+0

假設在所有平臺上運行所有應用程序是有益的或有利可圖的,這是天真的。 – Pierre

+0

假設您的程序永遠不會運行在您現在正在開發的程序之外的任何其他平臺上,這是天真的。當一個優秀的非平臺特定的API存在時,通過使用劣質API將自己綁定到平臺是完全愚蠢的。 – Clearer

1

如果你想有一個理智和成熟的解決方案,看看IBM's ICU。這裏有一個例子:

#include <iostream> 
#include <unicode/unistr.h> 
#include <string> 

int main(){ 
    icu::UnicodeString us("óóßChloë"); 
    us.toUpper(); //convert to uppercase in-place 
    std::string s; 
    us.toUTF8String(s); 
    std::cout<<"Upper: "<<s<<"\n"; 

    us.toLower(); //convert to lowercase in-place 
    s.clear(); 
    us.toUTF8String(s); 
    std::cout<<"Lower: "<<s<<"\n"; 
    return 0; 
} 

輸出:

Upper: ÓÓSSCHLOË 
Lower: óósschloë 

注:在後面的步驟SS不被視爲德國ß的資本

+0

這看起來像一個不錯的圖書館。但是,它的時鐘速度接近30MB。我的整個應用程序是21MB。 – Pierre

相關問題