- PR -

全角を含む文字列をバイト単位で部分取得

1
投稿者投稿内容
TERU
会議室デビュー日: 2003/03/20
投稿数: 2
投稿日時: 2003-03-20 13:33
VB6.0のプログラムを.NETへ移行しようとしているの
ですが、全角を含む文字列からバイト数(表示され
る幅)で部分取得したいのですが、VB6.0ではこういう
コードを書いていました。

Result = StrConv(MidB(StrConv(strBuffer, vbFromUnicode), 4, 4), vbUnicode)


VB.NETでは

Dim BytesA() as Byte
Dim BytesB() as Byte
Dim index as Integer

Dim SJIS as Encoding = System.Text.Encoding.GetEncoding("shift-jis")

BytesA = SJIS.GetBytes(strBuffer)

Redim Preserve BytesB(3)

For index = 3 to 5

BytesB(index - 3) = BytesA(index)

Next

Result = SJIS.GetString(BytesB)

というような、なんとも長いコードを書くことに
よって実現したのですが・・・納得いくコード
ではありません。

もうちょっと巧いやり方があるのではないかと
思うのですが、どなたか良い方法をご存じあり
ませんか?
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2003-03-20 14:20
コード:
Dim BytesA as Byte() = new Byte(4) {}
Dim SJIS as Encoding = System.Text.Encoding.GetEncoding("shift-jis")

Array.Copy(SJIS.GetBytes(strBuffer), 3, BytesA, 0, 4)
Result = SJIS.GetString(BytesA)


でどうでしょう。
Array.Copy()がポイントです。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-03-24 08:17
こんにちは。

 ちょっと気になったのですが、元の文字列が「AああA」のときは、どうなるのでしょう?
4バイトで切ると、「Aあ」+「あ」の1バイト目ですよね。表示させるだけだと大丈夫かもしれませんが、他の文字列を後ろに連結させるとおかしくなるような?

 C言語の感覚で言っているので、VBではどうなるのでしょう?
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2003-03-24 08:44
VBではどうなんでしょうね。
私の書いたソースでは、ぶった切れておかしな文字列になります。

MidB()ってバイト単位で扱うんだと思いましたので、TERUさんのソースでも同じように切れると思いますが。
TERU
会議室デビュー日: 2003/03/20
投稿数: 2
投稿日時: 2003-03-24 12:16
一郎さんご回答ありがとうございました。

Jittaさんがおっしゃるように、全角をぶった切っちゃうと
文字化けしますね。以前作ったときには最終1バイトが
ASCIIの範囲外だったらスペース置換えするコードを
書いたことがあったようななかったような・・・


VB6.0⇒VB.NETはあまりにも違って困ってしまいます。
前の言語でできてたことができなくなるって・・・
新鮮さもありますが、自分のコードに納得いかないこと
が多いです。

また教えていただくことがあるかもしれませんが、
よろしくお願いします。
はやいとこ解答できる側になりたいものです。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2003-03-24 14:06
>最終1バイトがASCIIの範囲外だったら

最後の1バイトだけで大丈夫ですか?
指定したバイトから指定したバイトまでを切り出すんですよね?
最初のバイトも気をつけないといけないと思いますが。

VB.NETは、VBという名前が付いているのでVBに慣れている人は簡単に移行できそうな雰囲気ですが、実はそうやって勘違いさせて.NETの世界にVB使いも引き込もうというMicrosoftのワナです。
VBの代わりや後釜として.NETを使っているわけではない私などは逆に、別の物なのにVBっぽさ爆発みたいなところが鼻につくんですけどね。

.NETプログラミング環境自体は確かに快適だと思います。
VBの事はすっかり忘れて、.NETの世界を堪能しましょう。


昔作った「全角文字の1バイト目かどうかを判定する関数」を載せておきます。
よろしければどうぞ。
使うのであれば、ちゃんとテストしてくださいね。

返り値:指定されたバイトが全角の1文字目であればtrue
arr - shift-JIS文字列のByte配列
number - 判定するバイト位置(先頭は0)
コード:
Private Function CheckFullFront(ByVal arr As Byte(), ByVal number As Integer) As Boolean
    Dim Error_Message as string = "指定されたバイト数が文字列のバイト数を超えているか、あるいは0未満です"
    Dim Full As Boolean = False '全角の一文字目かどうか(返り値)
    Dim point As Integer        '現在見ている文字列(配列)の位置

    '配列よりnumberの方が長いか0以下の場合
    If number < 0 OrElse arr.Length <= number Then
        Throw New ArgumentOutOfRangeException("number", Error_Message)
    End If

    For point = 0 To number
        If Full Then
        Full = False
    Else
        If (arr(point) >= &H80 And arr(point) <= &H9F) Or _
           (arr(point) >= &HE0 And arr(point) <= &HFF) Then
            Full = True
        End If
    End If
    Next point
    Return Full
End Function



1

スキルアップ/キャリアアップ(JOB@IT)