2019年4月7日日曜日

VB 文字化けで悩む

PC ドキュメントの保存に関して と言う投稿を書いたばかりなのですが、
其処で書いた 文字エンコード に翻弄されました。
あ~、恐ろしいかな、 文字化けの世界。
何とか、凌いではいますが ... 。


事の発端は、出来た!と思っていた筈の、プログラムで起こった事件。
文字化け!。
そうです。
英語記述が主体のプログラムコード用に書いていた、
とあるフロンエンドでの出来事です。
Linux の世界では 良くある 差分ファイル パッチ .patch ファイルを生成するものです。
対象のプログラムコード(対象ファイル群)は ほぼ 英語記述なので、
まさか、この様な事態になるとは思っていなかったのです。
バックエンドとなるプログラムは Linux の diff.exe を Windows に移植した、
古いものです。
CUI なので、GUI のフロントエンドを書いていた訳ですが、
そもそも、そのプログラムはテキストデータの差分を表示するものです。

そんな中、別のプログラムで生成したテキストファイルに軽微な間違いを発見し、
手直しをしたので、
これを使って見ようと、差分を抽出して見ると ... 。

あら、まぁ、 見事な 文字化け 。
テクストボックスに、謎の文字列が羅列されたのです。

テキストファイルの間違い は 日本語文字列冒頭に 半角スペースが紛れ込み、
ソートした時に、順番が狂うものでした。

当初のコードでは、
半角スペースが紛れ込んでいる事実は分かるのですが、
元の文字列(日本語)は 文字化け で ぐちゃぐちゃ。

まいったね!。  です。


diff.exe 文字化け で Web 検索して見れば、色々な情報がありますが、
どれも、解決の糸口にはなりそうにありません。

冷静になって考えましょう!。

バックエンドが CUI と言う事は、
立ち上がっている それ は コマンドプロンプト (cmd.exe) を利用しています。
確か、 cmd.exe の CodePage は 932 。  そう、日本語 Shift-JIS です。
片や、件の2つのファイルは UTF-8 。  CodePage なら 65001 。

う~ん。

バックエンドが 差分を正確に把握していると仮定すれば、
単に、表示が狂っているだけ? ... 。

そこで、 cmd.exe の StandardOutput を取り込んでいる テキストボックス の文字列に対し、
エンコードを変えてやる事にしました。

ビンゴ!。

CodePage 932 から 同 65001 への変換です。
説明用に、 既に、データ取得が済み、 テキストボックスに取り込まれているものとして、
其のコードを示します。
        Dim str0 As String = Me.TextBox1.Text
        Dim str1 As String = ""
        Dim bytesData As Byte()
        Dim cp As Integer = 932
        bytesData = System.Text.Encoding.GetEncoding(cp).GetBytes(str0)
        str1 = System.Text.Encoding.UTF8.GetString(bytesData)
        Me.TextBox1.Text = str1

最初は、上記のコードの様に、932 をハードコードしていました。
でも、これでは、日本語 Windows 専用になって仕舞いますね。
cmd.exe の chcp の返す文字列から数字を取得するにしても、
言語依存で、数字の前に付く 文字列は 不定ですから。
そこで、 cmd.exe が利用しているであろう TextInfo.ANSICodePage から、
Dim cp As Integer = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage
として見ました。

霧が晴れる様に、もやもや が 何処に消え去ってくれました。


UTF-8 のファイル限定になって仕舞いますが、
どうせ、これを使う対象ファイル群は UTF-8 ですから、
良し! としましょうか。

これで、一件落着。  :)



0 件のコメント:

コメントを投稿