SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

C++/CLI: とある文字列の相互変換(コンバージョン)

マーシャル・ライブラリ、Encoder/Decoder、ICUによる文字列変換


.NETに頼らない文字コード変換

 ついでにもうひとつ。.NETに頼らず、native-C/C++の範囲で文字コードを変換する方法です。残念ながらC/C++の標準ライブラリは様々な文字コードに対応した変換機能をサポートしてくれません。native世界での文字コード変換ライブラリで僕が愛用しているのがIBMのOpenSource:ICU(International Components for Unicode)です。ICUを使って上記UnicodeConverterをC++で実装してみました。

/*
 * ICU による文字コード変換
 */
#include <unicode/ucnv.h>
#include <string>

class UnicodeConverter {

private:
  UErrorCode error_;
  UConverter* converter_;

public:
  explicit UnicodeConverter(const char* name) {
    converter_ = ucnv_open(name,&error_);
  }

  ~UnicodeConverter() {
    ucnv_close(converter_);
  }

  bool ok() const { return U_SUCCESS(error_) != 0; }

  std::string fromUnicode(const wchar_t* input, int size);
  std::wstring toUnicode(const char* input, int size);

  std::string fromUnicode(const std::wstring& input) 
    { return fromUnicode(input.data(), input.size()); }
  std::wstring toUnicode(const std::string& input)
    { return toUnicode(input.data(), input.size()); }
};

// Unicode -> MBCS
std::string UnicodeConverter::fromUnicode(const wchar_t* input, int size) {
  std::string result(ucnv_getMaxCharSize(converter_)*size,'\0');
  int len = ucnv_fromUChars(
    converter_,
    &result[0], result.size(), // 変換先のポインタとサイズ
    input,      size,          // 変換元のポインタをサイズ
    &error_
    ); 
  result.resize(len);
  return result;
}

// MBCS -> Unicode
std::wstring UnicodeConverter::toUnicode(const char* input, int size) {
    std::wstring result(size,L'\0');
  int len = ucnv_toUChars(
    converter_,
    &result[0], result.size(), // 変換先のポインタとサイズ
    input,      size,          // 変換元のポインタとサイズ
    &error_
  ); 
  result.resize(len);
  return result;
}

/*
 * おためし
 */

#include <iostream>
#include <locale>

using namespace std;

int main() {

  wcout.imbue(locale("japanese"));

  // "JIS文字列" のJIS(iso-2022-jp)表現↓
  string jis = "\x4A\x49\x53\x1B\x24\x42\x4A\x38\x3B\x7A\x4E\x73\x1B\x28\x42";

  UnicodeConverter jis_converter("iso-2022-jp");

  // JIS → UNICODE
  wstring unicode = jis_converter.toUnicode(jis);
  wcout << L'[' << unicode << L']' << endl;

  // UNICODE → JIS
  string result = jis_converter.fromUnicode(unicode);
  if ( jis == result ) {
    wcout << L"元の文字列と一致しました!" << endl;
  }  

  // UNICODE → SJIS
  UnicodeConverter sjis_converter("shift_jis");
  result = sjis_converter.fromUnicode(unicode);
  cout << '[' << result << ']' << endl;

}

次のページ
おまけ: CLRフォームアプリケーションのフォーム名変更

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4774 2010/01/27 11:01

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー