Macos 在使用ICU在OS X上编译boost::locale时更正为_upper()
在OS X上使用默认设置编译Boost 1.59.0时使用iconv库。当使用带有UTF8字符的Macos 在使用ICU在OS X上编译boost::locale时更正为_upper(),macos,boost,unicode,locale,icu,Macos,Boost,Unicode,Locale,Icu,在OS X上使用默认设置编译Boost 1.59.0时使用iconv库。当使用带有UTF8字符的boost::locale::to_upper()时,iconv会导致类似“GRüßEN”的输入结果,如“GRüEN”。如您所见,某些字符的大小写不正确 我了解到修复方法是使用ICU而不是iconv,因此我开始使用ICU构建Boost。对于我的用例,我遵循的方法如下: 下载unix tar ball(不是ZIP,它有CR/LF行结尾,不起作用)。去焦油吧 将第1414行的文件boost/libs/fi
boost::locale::to_upper()
时,iconv会导致类似“GRüßEN”
的输入结果,如“GRüEN”
。如您所见,某些字符的大小写不正确
我了解到修复方法是使用ICU而不是iconv,因此我开始使用ICU构建Boost。对于我的用例,我遵循的方法如下:
boost/libs/filesystem/src/operations.cpp
中的代码修改为#if 0
,以便始终执行回退代码。否则,我会得到一个链接错误,告诉您,fchmodat
在OS X 10.9中不可用http://site.icu-project.org/download/56#TOC-ICU4C下载
。去焦油吧/configure--enable static--disable shared cxflags=“-std=c++14”-prefix=“
gnumake&&gnumake安装
boost\u 1\u 59\u 0/
/bootstrap.sh toolset=darwin macosx version=10.11 macosx version min=10.8——使用icu=
/b2 toolset=darwin--without-mpi optimization=speed cxflags=“-arch x86_64-fvisibility=hidden-fvisibility inlines hidden-std=c++14-stdlib=libc++-ftemplate depth=512”linkflags=“-stdlib=libc++”--recognize boost.locale.iconv=off boost.locale.icu=on-sICU路径=-link=static stage
Boost::locale::to_upper()
现在完全跳过UTF8字符,并返回“GREN”
作为输入,如“grüßEN”
测试代码如下所示:
static boolean defaultLocaleWasInitialized = false;
...
void String::p_initDefaultLocale(void)
{
boost::locale::generator gen;
std::locale defaultLocale = gen("");
std::locale::global(defaultLocale);
std::wcout.imbue(defaultLocale);
}
...
String::Pointer String::uppperCaseString(void) const
{
if (!defaultLocaleWasInitialized) {
String::p_initDefaultLocale();
defaultLocaleWasInitialized = true;
}
auto result = boost::locale::to_upper(*this);
auto newString = String::stringWith(result.c_str());
return newString;
}
...
TEST(Base_String, UpperCaseString_StringWithLowerCaseCharacters_ReturnsOneWithUpperCaseCharacters)
{
auto test = String::stringWith("Mp3 grüßEN");
auto result = test->uppperCaseString();
ASSERT_STREQ("MP3 GRÜSSEN", result->toUTF8());
}
有没有关于我错在哪里的建议?好吧,这是正确的提升行为。Boost在本地化方面有局限性,例如它将
ß
视为单个代码点,并且不能将其大写为SS
。因此,您的代码不会出错,这只是Boost库的一个问题:某些UTF8字符的确切行为取决于平台
Boostß
限制:和(特别是评论)
平台依赖性:
如果您希望它被正确翻译,您可能需要另一个库。本地化很难
iconv
在不同编码之间转换字符串,但不进行大小写转换。你应该包括一个小测试程序的代码来显示问题。将代码添加到我的问题中。试图找到我读到的ICU需要进行适当转换的地方。使用boost库是否正确转换字符串?在字符串文本中包含非ascii字符(如“Mp3 grüßEN”
是未定义的行为。您必须以其他方式确保您的字符串包含您希望它包含的字符,例如,通过UTF-8编码该字符串并对结果字节进行如下编码:ü→ <代码>“\xc3\xbc”。你使用的任何库都必须知道你使用了什么编码。使用-DU\u CHARSET\u重新编译ICU是\u UTF8=1
。当使用字符串literal“GR\xC3\xBC en”
作为测试时,我得到了相同的结果(跳过的字符)。我不确定输入是否是问题所在。如果我复制的代码取自我的《格伦·格伦与格伦·格伦》,关于boost::locale(无ICU),您可能是正确的,但ICU的行为不依赖于平台,我的理解是boost与ICU的行为不依赖于平台。boot::locale自己的文档提到,大写字母ß
的行为是受支持的,不管怎样,可以肯定地说忽略字符(正如我所看到的)不是正确的行为,所以我的问题仍然是,我从头编译这些库的错误在哪里。