読者です 読者をやめる 読者になる 読者になる

【C++】UTF8

UTF8文字列処理のメモです。

いまだにUTF8を使ってサーバーとやり取りしてます。
たまに、表示文字数をカウントしたり、文字数が多すぎる場合途中から"..."を表示したり
結構困ります。。。

C++11からstd::u32stringを追加されて意外と便利です。
std::codecvt_utf8と組み合わせば、もう怖くない〜

例えば

文字数をカウントしたり

#include <iostream>
#include <codecvt>

size_t strlen(const std::string& s)
{
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv;
    return conv.from_bytes(s).size();
}
int main()
{
    std::string utf8 = u8"2015年1月24日";
    std::cout << "size:" << strlen(utf8) << std::endl; // size:10
}

文字列の一部分取得したり

#include <iostream>
#include <codecvt>

std::string substr(const std::string& s,size_t pos = 0, size_t len = std::string::npos)
{
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv;
    auto u32string = conv.from_bytes(s); // UTF8 -> UTF32
    auto sub = u32string.substr(pos,len); // 部分取得
    return conv.to_bytes(sub); // UTF32 -> UTF8にして返す
}
int main()
{
    std::string utf8 = u8"𠮷野家牛丼";
    std::cout << substr(utf8,0,3) << std::endl; // 𠮷野家
}

サロゲートペアも無問題、めでたしめでたし〜

追記

2015/12/06
VisualStudio2015 では コンパイルエラーになると報告がありました
検証環境が用意できたので結果を報告します
結論から言うと、この記事のサンプルコードは問題ありません。

VS 2015 RC linker std::codecvt error
上記リンクによると、これはVisualStudio2015既知の不具合です
回避策として char32_t を int32_t に変更すればコンパイルが通ります

修正確認したらまた追記する