Help us understand the problem. What is going on with this article?

そろそろWindowsでUTF-16とShift-JISの変換方法をC++erらしくまとめようか

More than 1 year has passed since last update.

Win32APIには御存知の通りWideCharToMultiByte関数とMultiByteToWideChar関数があるが、わりと使うのは面倒くさい。

そもそも当たり前だけどstd::basic_string<char_type>使えないし。

というわけでメモ代わりにまとめておく。locale周りはガバのプーさんだけどそこは勘弁して下さい。

結論

これでいいかと。なんとなくshrink_to_fit呼んでるけどこれ必要なのかねぇ

#include <string>
#include <windows.h>
#include <cstring>
std::wstring shift_jis_to_utf_16(const std::string& str)
{
    static_assert(sizeof(wchar_t) == 2, "this function is windows only");
    const int len = ::MultiByteToWideChar(932/*CP_ACP*/, 0, str.c_str(), -1, nullptr, 0);
    std::wstring re(len * 2 + 2, L'\0');
    if (!::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, &re[0], len)) {
        const auto ec = ::GetLastError();
        switch (ec)
        {
        case ERROR_INSUFFICIENT_BUFFER:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: ERROR_INSUFFICIENT_BUFFER"); break;
        case ERROR_INVALID_FLAGS:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: ERROR_INVALID_FLAGS"); break;
        case ERROR_INVALID_PARAMETER:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: ERROR_INVALID_PARAMETER"); break;
        case ERROR_NO_UNICODE_TRANSLATION:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: ERROR_NO_UNICODE_TRANSLATION"); break;
        default:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: unknown(" + std::to_string(ec) + ')'); break;
        }
    }
    const std::size_t real_len = std::wcslen(re.c_str());
    re.resize(real_len);
    re.shrink_to_fit();
    return re;
}
std::string utf_16_to_shift_jis(const std::wstring& str) {
    static_assert(sizeof(wchar_t) == 2, "this function is windows only");
    const int len = ::WideCharToMultiByte(932/*CP_ACP*/, 0, str.c_str(), -1, nullptr, 0, nullptr, nullptr);
    std::string re(len * 2, '\0');
    if (!::WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, &re[0], len, nullptr, nullptr)) {
        const auto ec = ::GetLastError();
        switch (ec)
        {
        case ERROR_INSUFFICIENT_BUFFER:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: ERROR_INSUFFICIENT_BUFFER"); break;
        case ERROR_INVALID_FLAGS:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: ERROR_INVALID_FLAGS"); break;
        case ERROR_INVALID_PARAMETER:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: ERROR_INVALID_PARAMETER"); break;
        default:
            throw std::runtime_error("in function utf_16_to_shift_jis, WideCharToMultiByte fail. cause: unknown(" + std::to_string(ec) + ')'); break;
        }
    }
    const std::size_t real_len = std::strlen(re.c_str());
    re.resize(real_len);
    re.shrink_to_fit();
    return re;
}

雑記

CP_ACPってところを変えればいろいろ出来たりする。例えばISO_8859_1なら西ヨーロッパ言語 - iso-8859-1からutf-16への変換ができる。
cf.)

あと、WideCharToMultiByte関数は第二引数にWC_NO_BEST_FIT_CHARSを指定せずに呼ぶと似た文字への変換が発生するらしい。
cf.)

参考サイト

追記

ちょっと違うけど
http://qiita.com/AsladaGSX/items/af50066dbbfd59991af9
なんかすごい頑張っている記事を見つけました、

yumetodo
ありきたりなC++erです。最近C++書いていません(あれっ
http://yumetodo.hateblo.jp/
qiitadon
Qiitadon(β)から生まれた Qiita ユーザー・コミュニティです。
https://qiitadon.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした