C++字符串代码点和代码单元的任何良好解决方案

Any good solutions for C++ string code point and code unit?

本文关键字:代码 任何良 解决方案 字符串 C++ 单元      更新时间:2023-10-16

在Java中,字符串有方法:

length()/charAt(), codePointCount()/codePointAt()

C++11 有std::string a = u8"很烫烫的一锅汤";

a.size()是 char 数组的长度,不能索引 unicode char。

字符串中的 unicode 是否有任何解决方案C++?

我通常在执行字符操作之前将UTF-8字符串转换为宽UTF-32/UCS-2字符串。 C++实际上确实为我们提供了执行此操作的功能,但它们不是很用户友好,所以我在这里编写了一些更好的转换函数:

// This should convert to whatever the system wide character encoding 
// is for the platform (UTF-32/Linux - UCS-2/Windows)
std::string ws_to_utf8(std::wstring const& s)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> cnv;
    std::string utf8 = cnv.to_bytes(s);
    if(cnv.converted() < s.size())
        throw std::runtime_error("incomplete conversion");
    return utf8;
}
std::wstring utf8_to_ws(std::string const& utf8)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> cnv;
    std::wstring s = cnv.from_bytes(utf8);
    if(cnv.converted() < utf8.size())
        throw std::runtime_error("incomplete conversion");
    return s;
}
int main()
{
    std::string s = u8"很烫烫的一锅汤";
    auto w = utf8_to_ws(s); // convert to wide (UTF-32/UCS-2)
    // now we can use code-point indexes on the wide string
    std::cout << s << " is " << w.size() << " characters long" << 'n';
}

输出:

很烫烫的一锅汤 is 7 characters long

如果要与UTF-32进行转换,而不考虑平台,则可以使用以下(未经充分测试(转换例程:

std::string utf32_to_utf8(std::u32string const& utf32)
{
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> cnv;
    std::string utf8 = cnv.to_bytes(utf32);
    if(cnv.converted() < utf32.size())
        throw std::runtime_error("incomplete conversion");
    return utf8;
}
std::u32string utf8_to_utf32(std::string const& utf8)
{
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> cnv;
    std::u32string utf32 = cnv.from_bytes(utf8);
    if(cnv.converted() < utf8.size())
        throw std::runtime_error("incomplete conversion");
    return utf32;
}

注意:C++17 std::wstring_convert起已弃用

但是,我仍然更喜欢使用它而不是第三方库,因为它是可移植的,它避免了外部依赖,在提供替换之前不会删除它,并且在所有情况下都可以轻松替换这些功能的实现,而无需更改使用它们的所有代码。

相关文章: