codecvt

2
Egtra (ysk-noh) @egtra

VC++のlocaleは言語・地域そしてコードページを指定可能。ってことはもしかして、UTF-8のCPを指定したら、UTF-8を読み書きできるcode_cvtが作れる?

2010-12-21 22:33:51
Egtra (ysk-noh) @egtra

UTF-8のCPを持つlocale作成、code_cvtのfacet取得がエラーにならなかったとする。実際の変換が成功ならいいが、変換失敗でもConnectにフィードバック投げる価値ありだと思う、直すかどうかの判断を仰ぐといことで。

2010-12-21 22:45:12
Egtra (ysk-noh) @egtra

そういえば、この前のVC++でUTF-8のCPを持つlocaleとcode_cvt作れないか?問題は2005だとだめだった。

2010-12-23 22:09:38
Egtra (ysk-noh) @egtra

setlocaleがだめ。UTF-8を指定するとエラーを返すようになっていた。そのせいでlocaleコンストラクタも例外を投げる。codecvt_bynameで直接作るのもだめ。コンストラクタは例外投げないけど、結局どっかで弾いているらしく変換できない。

2010-12-23 22:12:43
Egtra (ysk-noh) @egtra

VC++ 2010はC++0xのcodecvt_utf8/codecvt_utf16/codecvt_utf8_utf16を持っているからもういいやと思ってしまった。

2010-12-23 22:14:25
Egtra (ysk-noh) @egtra

もしかして、wchar_t←→UTF-8/16またはUCS-2/4の変換を行う方法ってC++0x標準に用意されていない?

2010-12-23 22:30:48
Egtra (ysk-noh) @egtra

Windows/Linux/Mac OS X等wchar_tがUTF-16/32: wchar_t*をchar16/32_t*へreinterpret_cast。その他: wchar_t→charへ変換後、codecvt<char16/32_t,char,mbstate_t>使用

2010-12-23 22:38:30
Egtra (ysk-noh) @egtra

汎用的にwchar_tとUTF-8/16/32の変換を行なうとしたら、こんな感じになるのだろうか。どこが汎用的なんだろうかという気もする。

2010-12-23 22:39:36
Egtra (ysk-noh) @egtra

せめて、wchar_tがUCS-2/である場合に定義されるマクロってないかな。あとで調べる。

2010-12-23 22:40:40
相沢陽菜 @fetus_hina

@egtra 規格上 wchar_t は UNICODE あるとは限らないんじゃないかなーと

2010-12-23 22:41:41
Egtra (ysk-noh) @egtra

@fetus_hina そうなんです。だから、1つ前の発言 http://bit.ly/h1OgJL のように、どうしたらいいのかなと考えていたというわけです。

2010-12-23 23:10:44
相沢陽菜 @fetus_hina

@egtra 何も決まっていない以上、どうしようもないとしか。現実解としてはマクロのifdefとか駆使して「対応環境」全てのパターンに場当たり対応…

2010-12-23 23:14:21
Egtra (ysk-noh) @egtra

うげげ、codecvt<char16_t, char, mbstate_t>はUTF-16とUTF-8、codecvt<char32_t, char, mbstate_t>はUTF-32とUTF-8の変換と書いてある。従来のマルチバイト文字列とUTF系との変換はどうしたらいいの?

2010-12-23 23:15:07
Egtra (ysk-noh) @egtra

@fetus_hina ええ、まったくその通りですよね。 http://bit.ly/h1OgJL も同路線です。

2010-12-23 23:18:27
Egtra (ysk-noh) @egtra

あれか、Unix系だと環境変数LANG/LC_CTYPE/LC_ALLからキャラクタセット指定の部分を抜き出せばいいのか(コマンドラインオプションなどでオーバーライド可能だとなお良し)。それを引数にiconvなりなんなりでUTF系へ変換と。

2010-12-23 23:32:35
Egtra (ysk-noh) @egtra

いいのかそれでって気しかしないけど、少なくともWindowsとPOSIXはカバーできる。Windowsはさっきも言ったように、wchar_tとchar16_t間でreinterpret_cast。

2010-12-23 23:35:23
Egtra (ysk-noh) @egtra

おお、Cにはmbrtoc16/c16rtombとmbrtoc32/c32rtombが提案されているのか!これだよこれ。これのC++版を探していたんだよ。

2010-12-23 23:38:59
Egtra (ysk-noh) @egtra

最悪これをラップすればいいというわけでだいぶましな状況になったと言える(C++0xにそんなのないという問題はさておき)。マルチバイト文字列とchar16/32_t文字列間の変換がない問題、Ad-hoc会議前に早く気付かないといけなかった。

2010-12-23 23:42:27
Egtra (ysk-noh) @egtra

defined __STDC_ISO_10646__ && sizeof (wchar_t) == 2でwchar_tがUCS-2ってのは許されるのかな?

2010-12-23 23:52:05
Egtra (ysk-noh) @egtra

まあいいや、基本はwchar_t←→char←(mbrtoc32/c32rtomb)→char32_t、wchar_tがUTF-16/32な環境(各種マクロを駆使して判定)はreinterpret_castでchar16/32_tへ。

2010-12-23 23:55:54
Egtra (ysk-noh) @egtra

wchar_tとchar16/32_tとの変換にcharを挟むと、Windows/Linuxのようなwchar_tがUnicodeでcharがマルチバイト文字列(UTF-8以外)な環境でアウトなのよね。

2010-12-23 23:58:12
Egtra (ysk-noh) @egtra

VC++10とCygwin 1.7のgcc(付属3.4.4と自前4.5.1)では__STDC_ISO_10646__が定義されていない件。_WIN32も判定条件に加えてやるしかないんだろうなあ。

2010-12-24 00:02:19
Egtra (ysk-noh) @egtra

さっきのwchar_t←→char←(mbrtoc32/c32rtomb)→char32_tでchar16_tを省いたのは書くのが面倒だったから。他意はない。

2010-12-24 00:04:44
Egtra (ysk-noh) @egtra

あ、mbrtoc16/c16rtombとmbrtoc32/c32rtombはC++0xにもあるじゃない!これでだいぶましになった。で、こいつらに対応するcodecvt特殊化または派生クラスがあれば問題解決なんですが。

2010-12-24 00:07:40
Egtra (ysk-noh) @egtra

UTF-8とUTF-16/32の変換はcodecvt_utf*に任せて、codecvtのchar16/32_tに関する特殊化は、mbrtoc16/c16rtombとmbrtoc32/c32rtomb同様のマルチバイト文字との変換が行なわれるべきだと思う。

2010-12-24 00:10:16