我正在开展一个项目,其中区分大小写的操作需要用不区分大小写的操作替换。在对此进行一些阅读之后,要考虑的数据类型是:
如果我错过了列表中的任何内容,请告诉我。
上面是否需要单独处理或者是否有C ++库可以处理它们而不涉及数据类型?
具体做法是:
boost库是否支持此功能?如果是,是否有关于如何使用API的示例或文档?
我了解了IBM的Unicode国际组件(ICU)。这是一个为不区分大小写的操作提供支持的库吗?如果是,是否有关于如何使用API的示例或文档?
最后,上述(和其他)方法中哪一个更好,为什么?
谢谢!
根据评论和答案,我写了一个示例程序来更好地理解这一点:
#include <iostream> // std::cout
#include <string> // std::string
#include <locale> // std::locale, std::tolower
using namespace std;
void ascii_to_lower(string& str)
{
std::locale loc;
std::cout << "Ascii string: " << str;
std::cout << "Lower case: ";
for (std::string::size_type i=0; i<str.length(); ++i)
std::cout << std::tolower(str[i],loc);
return;
}
void non_ascii_to_lower(void)
{
std::locale::global(std::locale("en_US.UTF-8"));
std::wcout.imbue(std::locale());
const std::ctype<wchar_t>& f = std::use_facet<std::ctype<wchar_t> >(std::local
std::wstring str = L"Zoë Saldaña played in La maldición del padre Cardona.";
std::wcout << endl << "Non-Ascii string: " << str << endl;
f.tolower(&str[0], &str[0] + str.size());
std::wcout << "Lower case: " << str << endl;
return;
}
void non_ascii_to_upper(void)
{
std::locale::global(std::locale("en_US.UTF-8"));
std::wcout.imbue(std::locale());
const std::ctype<wchar_t>& f = std::use_facet<std::ctype<wchar_t> >(std::local
std::wstring str = L"¥£ªÄë";
std::wcout << endl << "Non-Ascii string: " << str << endl;
f.toupper(&str[0], &str[0] + str.size());
std::wcout << "Upper case: " << str << endl;
return;
}
int main ()
{
string str="Test String.\n";
ascii_to_lower(str);
non_ascii_to_upper();
non_ascii_to_lower();
return 0;
}
输出结果为:
Ascii string:Test String。 小写:测试字符串。
非Ascii字符串:▒▒▒▒▒ 大写:▒▒▒▒▒
Non-Ascii string:Zo▒Salda▒a在Lamaldici▒ndelpadre Cardona中出场。 小写:zo▒salda▒a在lamaldici▒ndelpadre cardona中播放。
非ascii字符串虽然似乎转换为大写和小写,但某些文本在输出中不可见。为什么是这样?
总的来说,示例代码看起来不错吗?
答案 0 :(得分:2)
我对这个问题感到有些惊讶。对boost case conversion
的简单搜索提出了第一个条目:Usage - 1.41.0 - Boost,其中有一个案例转换条目。
搜索stl case conversion
的条目tolower - C++ Reference - Cplusplus.com也会显示如何使用STL进行转换。
要进行不区分大小写的搜索,请将两者都转换为大写或大写并进行比较。
来自boost.org的代码示例:
string str1("HeLlO WoRld!");
to_upper(str1); // str1=="HELLO WORLD!"
来自Cplusplus.com的示例:
// tolower example (C++)
#include <iostream> // std::cout
#include <string> // std::string
#include <locale> // std::locale, std::tolower
int main ()
{
std::locale loc;
std::string str="Test String.\n";
for (std::string::size_type i=0; i<str.length(); ++i)
std::cout << std::tolower(str[i],loc);
return 0;
}
对于ASCII字符(ASCII值<128的字符),应该没有问题。如果您使用的是MCBS,则可能需要将locals用于代码页。 Unicode应该没有问题AFAIK。
关于马特乔丹的评论:
此请求的真正问题是许多语言都具有案例转换的上下文要求 - 例如希腊语中的大写sigma 0x3A3应该变为0x03C3或0x03C2,具体取决于它是否在单词的末尾。
如果boost库支持这个,我会感到惊喜。你必须测试它并报告错误,如果他们不。他们的页面上没有参考说明他们是否进行任何上下文案例转换。解决方法可能是测试转换为小写和比较,以及转换为大写和比较。如果其中任何一个为真,那么就有一个匹配,这应该适用于99.99%的情况。
Bjarne Stroustrup撰写的一篇有趣的论文,发现here,是关于Locales的好读物。
答案 1 :(得分:1)
你已经对提升有了很好的答案。这里有一些补充说明:
字符编码
ASCII字符以7位编码。 ISO 8859-1和windows-1252通过使用第8位用一组有限的国际字符扩展ASCII。
Unicode标准进一步扩展了ASCII,并在32位上定义。有几种编码可供使用:32位上的UTF32是最简单的(1个unicode字符= 1个字符),但UTF16和UTF8编码允许使用较小的编码来存储Unicode文本字符。
为了使其更加困难,不同的操作系统使用不同的约定。在linux上,wchart_t
通常是用于unicode的32位宽字符,wstring
是基于wchar_t
的字符串,char
使用UTF8编码。在Windows wchar_t
上定义为16位,因为Windows&#39;本机编码是UCS-2(unicode的子集),char
通常被理解为win1252。
处理字符大小和编码
因此,要回顾您的问题,需要考虑两个方面:
存储 - 如果你想要一个适合所有人的大小,你可以使用char32_t和任何unicode字符一样保存ASCII。并使用basic_string<char32_t>
或u32string
作为字符串,它支持您用于处理普通字符串的所有函数。或者你可以使用普通字符串并遵守UTF 8 everywhere。
编码 - 您的应用程序如何解释您的char中包含的值,以及执行转换为大写或大写的操作。这在适用的locale
中定义。
幸运的是,C ++标准库可以应对所有这些方面:
其他图书馆
ICU库似乎不提供不区分大小写的比较。它为文本处理提供支持,例如,使用排序规则等迭代文本元素。
我建议继续使用标准库或提升,因为他们享有广泛的支持。