问题:有一种方法具有相应的测试用例,可以在一台机器上运行而在另一台机器上失败(详情如下)。我认为代码有问题,导致它偶然在一台机器上工作。不幸的是我找不到问题。
请注意,std::string 和 utf-8 编码的使用是我没有真正影响的要求。使用 C++ 方法完全没问题,但不幸的是我什么都没找到。因此使用 C 函数。
方法:
std::string firstCharToUpperUtf8(const string& orig) {
std::string retVal;
retVal.reserve(orig.size());
std::mbstate_t state = std::mbstate_t();
char buf[MB_CUR_MAX + 1];
size_t i = 0;
if (orig.size() > 0) {
if (orig[i] > 0) {
retVal += toupper(orig[i]);
++i;
} else {
wchar_t wChar;
int len = mbrtowc(&wChar, &orig[i], MB_CUR_MAX, &state);
// If this assertion fails, there is an invalid multi-byte character.
// However, this usually means that the locale is not utf8.
// Note that the default locale is always C. Main classes need to set them
// To utf8, even if the system's default is utf8 already.
assert(len > 0 && len <= static_cast<int>(MB_CUR_MAX));
i += len;
int ret = wcrtomb(buf, towupper(wChar), &state);
assert(ret > 0 && ret <= static_cast<int>(MB_CUR_MAX));
buf[ret] = 0;
retVal += buf;
}
}
for (; i < orig.size(); ++i) {
retVal += orig[i];
}
return retVal;
}
考试:
TEST(StringUtilsTest, firstCharToUpperUtf8) {
setlocale(LC_CTYPE, "en_US.utf8");
ASSERT_EQ("Foo", firstCharToUpperUtf8("foo"));
ASSERT_EQ("Foo", firstCharToUpperUtf8("Foo"));
ASSERT_EQ("#foo", firstCharToUpperUtf8("#foo"));
ASSERT_EQ("ßfoo", firstCharToUpperUtf8("ßfoo"));
ASSERT_EQ("Éfoo", firstCharToUpperUtf8("éfoo"));
ASSERT_EQ("Éfoo", firstCharToUpperUtf8("Éfoo"));
}
失败的测试(仅发生在两台机器中的一台上):
Failure
Value of: firstCharToUpperUtf8("ßfoo")
Actual: "\xE1\xBA\x9E" "foo"
Expected: "ßfoo"
两台机器都安装了语言环境 en_US.utf8。然而,他们使用不同版本的 libc。它可以在带有 GLIBC_2.14 的机器上工作,与编译位置无关,并且不能在另一台机器上工作,而它只能在那里编译,否则它缺少正确的 libc 版本。
无论哪种方式,都有一台机器可以编译此代码并在它失败时运行它。代码一定有问题,我想知道是什么。指向 C++ 方法(尤其是 STL)也很好。由于其他外部要求,应避免使用 Boost 和其他库。