我无法使用C ++中的tolower()函数将字符串转换为小写。使用普通字符串时,它会按预期工作,但不会成功转换特殊字符。
我如何使用我的功能:
string NotLowerCase = "Grüßen";
string LowerCase = "";
for (unsigned int i = 0; i < NotLowerCase.length(); i++) {
LowerCase += tolower(NotLowerCase[i]);
}
例如:
3和4无法正常工作,因为您可以看到
如何解决此问题?我必须保留特殊的字符,但是小写。
答案 0 :(得分:5)
来自tolower
的示例代码(如下)显示了您如何解决此问题;你必须使用默认的“C”语言环境以外的东西。
#include <iostream>
#include <cctype>
#include <clocale>
int main()
{
unsigned char c = '\xb4'; // the character Ž in ISO-8859-15
// but ´ (acute accent) in ISO-8859-1
std::setlocale(LC_ALL, "en_US.iso88591");
std::cout << std::hex << std::showbase;
std::cout << "in iso8859-1, tolower('0xb4') gives "
<< std::tolower(c) << '\n';
std::setlocale(LC_ALL, "en_US.iso885915");
std::cout << "in iso8859-15, tolower('0xb4') gives "
<< std::tolower(c) << '\n';
}
您可能还会将std::string
更改为std::wstring
,这是许多C ++实现中的Unicode。
wstring NotLowerCase = L"Grüßen";
wstring LowerCase;
for (auto&& ch : NotLowerCase) {
LowerCase += towlower(ch);
}
Microsoft的指导是“Normalize strings to uppercase”,因此您可以改为使用toupper
或towupper
。
请记住,逐字符转换可能不适用于某些语言。例如,在德国使用德语,使Grüßen全部为大写,将其转换为GRÜESSEN(尽管现在有capital ẞ)。还有许多其他“问题”,如组合字符;如果你正在用字符串进行真正的“生产”工作,你真的想要一种完全不同的方法。
最后,C ++对管理语言环境提供了更为复杂的支持,有关详细信息,请参阅<locale>
。
答案 1 :(得分:1)
我认为最便携的方法是使用用户选择的语言环境,这是通过将语言环境设置为""
(空字符串)来实现的。
std::locale::global(std::locale(""));
将语言环境设置为程序运行时使用的任何语言环境,它会影响在多字节和宽字符字符之间进行转换的标准字符转换例程(std::mbsrtowcs&amp; std::wcsrtombs)
然后,您可以使用这些函数将系统/用户选择的多字节字符(例如UTF-8
)转换为系统标准宽字符代码,这些代码可用于运行std::tolower
的函数一次一个角色。
这很重要,因为像UTF-8
这样的多字节字符集无法使用std::tolower()
之类的单字符操作进行转换。
将宽字符串版本转换为大写/小写后,可以将其转换回系统/用户多字节字符集,以便打印到控制台。
// Convert from multi-byte codes to wide string codes
std::wstring mb_to_ws(std::string const& mb)
{
std::wstring ws;
std::mbstate_t ps{};
char const* src = mb.data();
std::size_t len = 1 + mbsrtowcs(0, &src, 3, &ps);
ws.resize(len);
src = mb.data();
mbsrtowcs(&ws[0], &src, ws.size(), &ps);
if(src)
throw std::runtime_error("invalid multibyte character after: '"
+ std::string(mb.data(), src) + "'");
ws.pop_back();
return ws;
}
// Convert from wide string codes to multi-byte codes
std::string ws_to_mb(std::wstring const& ws)
{
std::string mb;
std::mbstate_t ps{};
wchar_t const* src = ws.data();
std::size_t len = 1 + wcsrtombs(0, &src, 0, &ps);
mb.resize(len);
src = ws.data();
wcsrtombs(&mb[0], &src, mb.size(), &ps);
if(src)
throw std::runtime_error("invalid wide character");
mb.pop_back();
return mb;
}
int main()
{
// set locale to the one chosen by the user
// (or the one set by the system default)
std::locale::global(std::locale(""));
try
{
string NotLowerCase = "Grüßen";
std::cout << NotLowerCase << '\n';
// convert system/user multibyte character codes
// to wide string versions
std::wstring ws1 = mb_to_ws(NotLowerCase);
std::wstring ws2;
for(unsigned int i = 0; i < ws1.length(); i++) {
// use the system/user locale
ws2 += std::tolower(ws1[i], std::locale(""));
}
// convert wide string character codes back
// to system/user multibyte versions
string LowerCase = ws_to_mb(ws2);
std::cout << LowerCase << '\n';
}
catch(std::exception const& e)
{
std::cerr << e.what() << '\n';
return EXIT_FAILURE;
}
catch(...)
{
std::cerr << "Unknown exception." << '\n';
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
代码未经过严格测试
答案 2 :(得分:-6)
使用ASCII
string NotLowerCase = "Grüßen";
string LowerCase = "";
for (unsigned int i = 0; i < NotLowerCase.length(); i++) {
if(NotLowerCase[i]<65||NotLowerCase[i]>122)
{
LowerCase+='?';
}
else
LowerCase += tolower(NotLowerCase[i]);
}