鉴于string foo
,我已就如何使用cctype
' answers将字符转换为小写
tolower
transform(cbegin(foo), cend(foo), begin(foo), static_cast<int (*)(int)>(tolower))
但是我begun to consider locale
&#39; tolower
,可以像这样使用:
use_facet<ctype<char>>(cout.getloc()).tolower(data(foo), next(data(foo), foo.size()));
tolower
接受并返回int
这个事实,我认为这只是一些过时的C东西?答案 0 :(得分:6)
不幸的是,两者都同样糟糕。虽然std::string
假装是一个utf-8编码的字符串,但是非方法/函数(包括tolower),实际上是utf-8识别的。因此,tolower
/ tolower
+语言环境可能与单字节(= ASCII)字符一起使用,对于每一组其他语言,它们都会失败。
在Linux上,我使用ICU库。在Windows上,我使用CharUpper
功能。
答案 1 :(得分:4)
在第一种情况(cctype)中,隐含设置了语言环境:
根据字符将给定字符转换为小写 由当前安装的C语言环境定义的转换规则。
http://en.cppreference.com/w/cpp/string/byte/tolower
在第二个(区域设置)情况下,您必须明确设置区域设置:
如果c是大写,则将参数c转换为小写的等效值 字母和小写等价物,由ctype决定 locale loc的方面。如果没有可能的转换,则为该值 返回是不变的。
答案 2 :(得分:1)
应该注意的是,当cctype
的{{1}}被创建时,语言设计者 知道tolower
的{{1}}。它以两种主要方式改进:
locale
版本允许使用tolower
,即使是用户修改过的,也没有要求改组来自locale
的新facet ctype
以及之前LC_CTYPE
实现定义了
setlocale
类型的对象是表示为有符号数还是无符号数。LC_CTYPE
说明符强制char
个对象被签名
如果它是tolower
的JSFiddle for live demo版本的signed
版本,则会产生未定义行为的可能性:
无法表示为
char
且不等于cctype
因此unsigned char
EOF
版本的static_cast
版本需要额外的输入和输出cctype
:
tolower
由于transform(cbegin(foo), cend(foo), begin(foo), [](const unsigned char i){ return tolower(i); });
版本直接在locale
上运行,因此无需进行类型转换。
因此,如果您不需要在另一个char
中执行转换,那么您只是希望facet ctype
更喜欢transform
所需的lambda。您是否更喜欢cctype
版本:
locale