(労)が多い文字コード Cocoaで機種依存文字を変換するには? パート1

in

MySQLでデータを検索する簡単なCocoaアプリケーションを作成していますが、相変わらず文字コードで悩まされています。レガシーシステムから引き継いだEUCコードで格納されたデータをCocoaアプリで検索・表示するだけなんですが、いわゆる機種依存文字が使用されていることが発覚。元データはソラリス上のEUCデータ、これを一度WindowsサーバでShift-JISに変換した後、再度EUCに変換してMySQLに格納するという複雑な経緯をたどってMySQLに格納されたデータを直接参照してデータを取得・表示しています。もう考えただけでゾッとしますね。機種依存は無いって前提だったので、

set character set utf8;
select japanese_string from table_a where id = x;

としておいて、プログラムは

MYSQL_ROW row;
while((row=mysql_fetch_row(...)))
  {
     NSString* display_string = ;
       [NSString stringWithCString:row[i] encoding:NSUTF8StringEncoding]];
  }

としていたのですが、これだと機種依存文字(今回の発覚したのはローマ数字のV)は文字化けしてしまいます。さすがにMySQL上で機種依存文字の変換まで面倒を見てくれるわけではないのでどうしても生データ(EUCコードデータ)を受け取って自力で変換していくことに...

NSString* temp_string = 
  [NSString stringWithCString:row[i] encoding:NSJapaneseEUCStringEncoding]];
NSData* tempData = 
  [display_string dataUsingEncoding:NSShiftJISStringEncoding];
int length=[tempData length];
char* c=(char*)malloc(length);
memset(c,0x00,length);
[tempData getBytes:c length:length];
for(i=0; i<length; i++)
  {
    if (*(c+i)==0x87)
      { //ローマ数字を置換する
        if (((*(c+i+1)) >= 0x54) && ((*(c+i+1)) <= 0x5d))
          {
            *(c+i)   = 0x85; i++;
            *(c+i) += 0x4b;
          }
      }
  }

NSString* converted_string =  [[NSString alloc] initWithData:
     [NSData dataWithBytes:c length:length] encoding:NSShiftJISStringEncoding];
free(c);

なんとまぁ、原始的ですが一文字ずつチェックして変換するしか方法を思いつきませんでした。まず、EUCデータを直接受け取りあいだにNSStringをかませてShiftJISに変換してバイト列を取得。これを一文字ずつチェックして置換して復元してます。これでCP932のローマ数字(V:0x8758)をMacOSXのローマ数字(V:0x85A3)に置換できました。NSString自身の内部コードはUTF16なので一度NSStringに格納した後もう一度ShiftJISでエンコードして取り出す必要があるのは面倒ですが致し方なしということで諦め。これでローマ数字の文字化けは解消できました。後は、13区あたりの文字変換を片端から実装していけば終了...と思っていたのですが、さにあらず。まだまだ落とし穴はありました。それについては疲れたので次回に書くことにします。(つーか、まだ解決していない)

この記事のトラックバックURL:

http://hippos-lab.com/blog/trackback/234

Comments

HKさん、こんにちは。CocoaBreakはちょくちょく拝見させてもらっています。Cocoaについては勉強をはじめてまだ日が浅くわからないことだらけなんですよ。NSString:CFStringの関係もしっかりと把握できていないくらいです。ですので、少今後ともご指摘していただければうれしいです。

はじめまして。park15.wakwak.com/~concordia/cocoa_break/ の HK です。この記事とは関係ないですが、リンクさせていただきました。コメント等で問題等がありましたら、ご教示ください。ちなみにローマ字等の機種依存文字は書籍の編集を頼まれる時に毎回うっとおしい思いをしてきました。エンコーディング変換は、欠損バイトなどいろいろチェックしたほうがいい気が。私の場合、この手の作業は NSString より CFString でやります。


Apple Store(Japan)