当你开发一个应用程序时,需要将字符串转为小写形式。于是,你写下了的代码。
std::string name = "Hello World";
std::transform(name.begin(), name.end(), name.begin(), std::tolower);
乍看之下,使用 STL 的 std::transform 和 std::tolower 没什么问题,事实上却踩了三个坑:
1、std::tolower 不能直接使用
由于 std::tolower 并不是一个可寻址的函数,因此不能直接作为函数指针传递给 std::transform,需要改为:
std::transform(name.begin(), name.end(), name.begin(), [](unsigned char c){return std::tolower(c);});
2、字符类型匹配问题
众所周知,std::tolower 只适用于 unsigned char 范围内的字符,如果字符串中有非 ASCII 字符,比如中文、日文、韩文或特殊符号,以及宽字符字符串 std::wstring,std::tolower 都无法正确处理,甚至可能导致未定义行为。 因此,需要用到 std::towlower 但这仍然有问题,因为它无法正确处理 UTF-16 编码中的代理对(surrogate pairs),也就是那些需要两个 wchar_t 来表示的字符。
std::string name = L"Hello World";
std::transform(name.begin(), name.end(), name.begin(), [](Wchar_t c){return std::tolower(c);});