C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: VistaでChr(&HE0)の値が異なる


(過去ログ 80 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■47313 / inTopicNo.1)  VistaでChr(&HE0)の値が異なる
  
□投稿者/ tonton (15回)-(2010/02/25(Thu) 18:30:07)

分類:[VB6 以前] 

VB6.0を使用しています。
下記のコーディングがあるPGMでChr(&HE0)の戻り値が
Vistaとそれ以外のOS(XP、2000、2003など)で異なるんです。
VistaはSP2です。
他のコーディングの影響はここだけを抜き出して別PGMにしているのでありません。
どなたかお分かりになる方、環境で試せる方いたら宜しくお願いします。

Dim strTest As String * 2

strTest = Chr$(&H0) & Chr(&HE0)


引用返信 編集キー/
■47318 / inTopicNo.2)  Re[1]: VistaでChr(&HE0)の値が異なる
□投稿者/ 魔界の仮面弁士 (1508回)-(2010/02/25(Thu) 19:33:11)
No47313 (tonton さん) に返信
> 下記のコーディングがあるPGMでChr(&HE0)の戻り値が
> Vistaとそれ以外のOS(XP、2000、2003など)で異なるんです。
そもそも、Chr(&HE0) の結果は未定義です。

ヘルプの『ASCII 文字セット (128 - 255)』で確認してみると、表中の 224(&HE0) の箇所は、
『これらの文字は、Microsoft Windows ではサポートされていません。』とされていますので、
OS によって結果が異なっていたとしても、それは仕方が無いかと思いますよ。


> Dim strTest      As String * 2
> strTest = Chr$(&H0) & Chr(&HE0)
実際には、何の“文字”を指定したいのでしょうか?

String 型の変数には、通常、UTF-16 相当のバイナリが格納されることが期待されます。
(16bit 版の VB では ANSI ですが)

もし、『Unicode としての E0』([`a]の文字、Latin Small Letter A With Grave)を代入したいなら、
ChrW 関数を利用するようにしてください。終始 Unicode であつかい続ける限りは、
それが別の文字に変化してしまうことはありません。

一方、『Shift_JIS としての E0』だとしたら、これは全角文字で使われる領域なので、
これ単独で文字となる事はありませんので、文字として扱うことはそもそも不可能です。

あるいは、データ通信などで、『バイナリとしての E0』を期待するのであれば、
String ではなく Byte 配列を使うべきですし、String しか選択肢が残されていないなら、
せめて ChrB を使うようにすべきかと。

引用返信 編集キー/
■47334 / inTopicNo.3)  Re[2]: VistaでChr(&HE0)の値が異なる
□投稿者/ tonton (17回)-(2010/02/26(Fri) 12:33:58)
ヘルプを見ました。確かにサポートされていないようです。

バイナリとしてのE0なので
本来であればおっしゃられるようにByte配列にするのでしょうが
元のPGMが変なコーディングをしているようです。
Stringに入れて、その後StrConvしているみたいな。
試しに

Dim strTest As String
Dim byteRtn() As Byte
Dim iLoop As Integer

strTest = Chr$(0)

For iLoop = 1 To 255 Step 1
strTest = strTest & Chr$(iLoop)
Next

byteRtn = StrConv(strTest, vbFromUnicode)

などして値を確認しましたが、
byteRtn(129)〜(159)と(224)〜(252)には0が入っており変換がうまくいっていないようです。
これもサポートされていない事と関係あるのでしょうか。
逆に(128)や(253)〜(255)などがうまくいっているのはたまたまなのでしょうか。

引用返信 編集キー/
■47340 / inTopicNo.4)  Re[3]: VistaでChr(&HE0)の値が異なる
□投稿者/ 魔界の仮面弁士 (1512回)-(2010/02/26(Fri) 14:10:35)
No47334 (tonton さん) に返信
> ヘルプを見ました。確かにサポートされていないようです。
このあたりの動作は、9x と NT 系でも違いがありましたが、
Vista でまた変わっていた事は私も知りませんでした。
(そもそも使うべきでは無いコードなので、動作が変更されても困りはしませんが)


> 元のPGMが変なコーディングをしているようです。
PGM というのは、program の事でしょうか?


> Stringに入れて、その後StrConvしているみたいな。
しなければ良いと思いますよ。

String 型をバイナリ データの入れ物として扱うのであれば、
「Chr で入れて vbFromUnicode で変換」するのではなく、
「ChrB で入れて、StrConv せずに扱う」ようにすれば、
少なくとも格納する時点においては、データは破損しないと思います。


> byteRtn(129)〜(159)と(224)〜(252)には0が入っており変換がうまくいっていないようです。
認識の違いだとは思いますが、そもそも StrConv 以前の問題として、
Chr 関数を使ったときに、どういう「文字」が返される事を期待していますか?

先述したように、String は Unicode 文字列を格納するためのものであり、
内部は UTF-16 相当のバイナリで管理されています。そのため、
vbFromUnicode / vbUnicode で相互変換できる場合というのは、その文字が
Unicode と一対一に対応している場合だけとなります。


そして 129(&H81) は、これ単独では「文字」として処理できません。
0x81 は日本語環境下においては 2 バイト文字として扱われる値であり、
それをどの Unicode 文字にマッピングするかは、おそらくは OS の処理に
依存しているのでしょうから、VB6 側でどうこうするものでは無いと思います。


さらに言えば、もしも Chr 関数で「文字」として扱えたからといって、
それを vbFromUnicode で元の値に復元できるかといえば、それは誤りです。

たとえば "≒" の文字を考えてみてください。

この文字は、0x8790 と 0x81e0 の二か所に割り当てられているのですが、
Unicode では U+2252 一か所にのみマッピングされています。そのため、
 s1 = ChrW(&H2252)
 s2 = Chr(&H81E0)
 s3 = Chr(&H8790)
はいずれも、0x2252 という同一バイナリにエンコードされることになります。

もちろん、0x2252 自体は "≒" としてデコード可能ですが、
だからといって、これを vbFromUnicode したところで、
元々の 81E0 / 8790 を区別して変換する事は不可能です。
http://support.microsoft.com/kb/170559/ja


繰り返しになりますが、バイナリとして扱うなら、Byte() や Stream で
管理すべきですし、どうしても String が必要なら、ANSI / Unicode の『変換』が
発生しないような処理命令のみを使うようにすれば、別のデータに化ける事はありません。

なお、ファイル入出力ステートメントや、ActiveX コンポーネント、API 呼び出しなどでは
暗黙的な ANSI / Unicode 変換が発生する可能性がありますので注意が必要です。



> 逆に(128)や(253)〜(255)などがうまくいっているのはたまたまなのでしょうか。
だと思います。シフトJIS においては、253〜255 のバイナリは、
1バイト文字でも 2バイト文字でも使われていませんし。


ちなみに、こうした変換問題が起きるのは vbFromUnicode/vbUnicode だけではありません。
今回の件とは無関係ですが、蛇足情報として:

&H0022["]  → vbWide → &HFF02[W]
&H0027[']  → vbWide → &HFF07[V]
&H005C[\]  → vbWide → 変化無し(&H005C[\])
&HFFE5[¥] →vbNarrow→ NT/2000では &H5C[\]、9X系では変化無し(&HFFE5[¥])
&HFF3C[\] →vbNarrow→ 変化無し(&HFF3C[\])
&H2018[‘] →vbNarrow→ &H0027[']
&H2019[’] →vbNarrow→ &H0027[']
&HFF07[V] →vbNarrow→ 9x系では変化無し(&HFF07)、NT/2000では &H0027[']
&H201C[“] →vbNarrow→ &H0022["]
&H201D[”] →vbNarrow→ &H0022["]
&HFF02[W] →vbNarrow→ 9x系では変化無し(&HFF02)、NT/2000では &H0022["]

引用返信 編集キー/
■47346 / inTopicNo.5)  Re[4]: VistaでChr(&HE0)の値が異なる
□投稿者/ tonton (18回)-(2010/02/26(Fri) 16:30:42)
確かにChrの戻り値になにを求めているかというと、
そのままByte配列に格納したりChrB使ってStrConv使わない方がもっともらしですよね。
それだけでは文字とみなさないのですから・・・
あくまでバイナリデータとして扱いたいだけなのでPGM(すいませんProgramです)
を直す事にします。
今まで動いていた事が奇跡なのとなぜ前任者はこのコーディングにしたんだろう。
ちなみにですけど
byteRtn(1) = &HE0
※byteRtn・・・byte配列
なんてコーディングをStrConvの後にやっているんですよ。
きっとStrConvで0が返ってきちゃっているからその部分だけセットしているんでしょうが。
本来の意味を知ってるならChrB使うなりByte配列に最初からセットするなりするんでしょうね。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -