ICU による文字コード変換ライブラリ
C++ で文字コードを変換するプログラムを作成したので紹介します.以下に実装する関数 encode を用いれば std::string, std::wstring 間で文字コードを変換できます.
文字コードの変換には代表的なライブラリとして libiconv と ICU とありますが,主にライセンス上の理由により今回は ICU を用います.
ICU による文字コード変換ついては「ICU 2.x : UnicodeString による文字コード変換」に非常に丁寧にまとめられているので,内部の動きについて知りたい方は是非ご覧下さい.
それでは以下に私の実装を示します.
encode.hpp
#ifndef ENCODE_HPP_20100822 #define ENCODE_HPP_20100822 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include <string> namespace string { // multibyte to widechar void encode(const std::string& codepage, const std::string& src, std::wstring& dst); std::wstring encode(const std::string& codepage, const std::string& src); // widechar to multibyte void encode(const std::wstring& src, const std::string& codepage, std::string& dst); std::string encode(const std::wstring& src, const std::string& codepage); // multibyte to multibyte void encode(const std::string& codepageSrc, const std::string& src, const std::string& codepageDst, std::string& dst); std::string encode(const std::string& codepageSrc, const std::string& src, const std::string& codepageDst); } #endif
encode.cpp
#include "encode.hpp" #include <unicode/ucnv.h> #include <vector> // multibyte to widechar void string::encode(const std::string& codepage, const std::string& src, std::wstring& dst) { const icu::UnicodeString ustr(src.c_str(), src.size(), codepage.c_str()); dst.assign(ustr.getBuffer(), ustr.getBuffer() + ustr.length()); } std::wstring string::encode(const std::string& codepage, const std::string& src) { std::wstring dst; encode(codepage, src, dst); return dst; } // widechar to multibyte void string::encode(const std::wstring& src, const std::string& codepage, std::string& dst) { const icu::UnicodeString ustr(src.c_str(), src.size()); const int32_t len = ustr.extract(0, ustr.length(), 0, codepage.c_str()); if (len > 0) { std::vector<char> buf(len); ustr.extract(0, ustr.length(), &buf[0], buf.size(), codepage.c_str()); dst.assign(buf.begin(), buf.end()); } else { dst.clear(); } } std::string string::encode(const std::wstring& src, const std::string& codepage) { std::string dst; encode(src, codepage, dst); return dst; } // multibyte to multibyte void string::encode(const std::string& codepageSrc, const std::string& src, const std::string& codepageDst, std::string& dst) { std::wstring intermediate; encode(codepageSrc, src, intermediate); encode(intermediate, codepageDst, dst); } std::string string::encode(const std::string& codepageSrc, const std::string& src, const std::string& codepageDst) { std::string dst; encode(codepageSrc, src, codepageDst, dst); return dst; }
encode.cpp に文字コードを変換する関数 encode を実装しました.encode.cpp をプロジェクトに加え(他のソースコードと一緒にコンパイル),encode.hpp を include することにより encode が使用可能になります.
以下のテストコードで encode の動作を確認できます.
test.cpp
#include "encode.hpp" #include <locale> #include <iostream> #pragma comment(lib, "icuuc.lib") int main() { std::wcout.imbue(std::locale("japanese")); // multibyte to widechar std::wcout << string::encode("shift_jis", "テスト") << std::endl; // shift_jis to utf16 std::wcout << string::encode("euc-jp", "\xA5\xC6\xA5\xB9\xA5\xC8") << std::endl; // euc-jp to utf16 std::wcout << string::encode("utf8", "\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88") << std::endl; // utf8 to utf16 // widechar to multibyte std::cout << string::encode(L"テスト", "shift_jis") << std::endl; // utf16 to shift_jis // multibyte to multibyte std::cout << string::encode("utf8", "\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88", "shift_jis") << std::endl; // utf8 to shift_jis return 0; }
以上です.
非常に単純な実装ですが,お役に立てると幸いです.