cppreference说std::ctype
提供基于经典“C”语言环境的字符分类。当我们创建这样的语言环境时,这是否正确:
std::locale loc(std::locale("en_US.UTF8"), new std::ctype<char>);
loc
的方面是否仍会根据“C”语言环境或Unicode语言对字符进行分类?如果按前者分类,为什么我们甚至将语言环境名称指定为“en_US.UTF8”?
答案 0 :(得分:2)
该标准要求默认构建 std::ctype<char>
通过§22.4.1.3.3[facet.ctype.char.statics]/1
static const mask* classic_table() noexcept;
返回:指向大小为
table_size
的数组的初始元素的指针,该数组表示“C”语言环境中字符的分类
分类成员函数is()
是根据table()
定义的classic_table()
,除非为ctype<char>
的构造函数提供了另一个表1} p>
我已更新cppreference以更恰当地符合这些要求(它也为std::ctype<wchar_t>
说“C”)
要回答第二个问题,使用std::locale loc(std::locale("en_US.UTF8"), new std::ctype<char>);
构造的语言环境将使用您指定的ctype facet(因此,“C”)来对窄字符进行分类,但它是多余的:简单字符的窄字符分类{ {1}}(至少在GNU实现中)完全相同:
std::locale("en_US.UTF8")
答案 1 :(得分:1)
根据我在C ++ 11N3376§22.4.1.1的工作草案中所读到的,std::ctype<char>
应该这样做:
Class ctype encapsulates the C library <cctype> features. istream members
are required to use ctype<> for character classing during input parsing.
The specializations required in Table 81 (22.3.1.1.1), namely ctype<char> and
ctype<wchar_t>, implement character classing appropriate to the
implementation’s native character set.
在那里没有提到C语言环境,cppreference可能是指<cctype>
中找到的函数。
答案 2 :(得分:0)
在C中,C语言环境适用,直到您从setlocale()
更改<locale.h>
的语言环境。 C ++可能也是如此,尽管您也可能有其他机制来设置区域设置。
您的陈述似乎会创建一个区域设置;但是,它并不清楚它是否将该语言环境置于默认语言环境中。然后可以使用该区域设置来指定比较:
ISO / IEC 14882:2011(C ++ 2011标准)的第22.3节标题为区域设置。它部分地说:
// 22.3.3, convenience interfaces:
template <class charT> bool isspace (charT c, const locale& loc);
template <class charT> bool isprint (charT c, const locale& loc);
此外,在标准稍后,它说:
22.3.1.5
locale
静态成员[locale.statics]
static locale global(const locale& loc);
1将全局语言环境设置为其参数。
2 效果:导致将来对构造函数locale()的调用返回参数的副本。如果 参数有一个名字,确实如此
std::setlocale(LC_ALL, loc.name().c_str());
否则,对C语言环境的影响(如果有的话)是实现定义的。其他没有库功能 比locale::global()
会影响locale()
返回的值。 [注意:数据争用见22.6 调用setlocale
时的注意事项。 - 结束记录]3 返回:
locale()
的前一个值。
因此,如果我希望
std::ctype
根据“en_US.UTF8”进行分类,我必须在运行上述行之前更改全局语言环境吗?
我从最初的引文中读到的是,鉴于您的loc
,您可以写下:
if (isspace(ch, loc)) { ... }
指定要显式使用的语言环境。如果您不想这样做,那么您需要调用std::locale::global(loc)
来设置全局区域设置,因此isspace()
的未加修改的调用将起作用:
if (isspace(ch)) { ... }