2011年7月11日月曜日

std::getline 知らんかった・・・

vc8の話ざんす。

  UNICODE で wide string な文字列の書かれたファイルを読み込んで、std::getline してたんですわ。
ルンルン気分で、boost::spirit::qi してたんですわ。いや、UTF-8 から utf8_codecvt_facet 使ったら、思いの他、メモリ食って遅くて、Windows7 が反応しなくなるぐらい酷くて、途中から UNICODE で試してみてたんですわ。
んだども、待てど暮らせど、いつまでたっても正しいはずのパーサに引っかからない。あれ?あれれ?UNICODE って、BOM 関係あったっけ?Big Endian?Little Endian ?とか、ファイルをちょこちょこ見ながら変換かけて読み直しても、パーサに引っかからないんですわ。

うーぉぉぉおおおおおお、どないなってんねーーーーん。って、文字列良く見たら、1行目の文字は正しくデータが入っている感じだが、2行目以後は Endian が逆になってる。なんじゃコレ???って、よくよく追ってみると、どうやら、0x0d 0x00 0x0a 0x00 のうちの 0x0a まで読み込んだ段階で終了しとる。

うーん???ロケールの設定は合ってるっぽいけど…。なんかいまいちだなー。MBCSとの絡みで、こんな仕様になっとるんやろか?wchar_t の型で、1文字だけずらすって勘弁してほすぃ。1byte だけ読み飛ばすなんて、メンバ関数無いやん。read ? 2文字すっ飛ばすんですが??? seekg(1, std::ios_base::cur ) 2文字すっ飛ばすんですが何か???

UNICODE 師寝

2011/07/13 追記:
突っ込みをいただいた。試しに、出力してバイナリで見たら SJIS に変換されてて、ある意味ショック・・・。wcout もディスプレイに、どういうカラクリで漢字を出力しているんだろう?と思ってたけど、謎が氷解した。勉強になりました。

で、昨今ではテキストデータを UTF-8 で貰う機会も増えてきた。ある意味、stream 系でのロケールは、C++の鬼門?正直、使えると思った事が無いけど、難しい問題だ・・・。 ISO-8859-1 なヨーロッパ系のコードでも、似たような現象で悩んでいる人がいる模様。

0 件のコメント: