2013-08-01 82 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

相关问题