バイト配列の値を文字列に変換するには?

解決


シル  2004-04-06 10:56:36  No: 112664  IP: [192.*.*.*]

vb.net2003で開発をしています。

Dim strString As String = "1234567890"
Dim BytesA(Len(strString)) As Byte
Dim BytesWK(Len(strString)) As Byte
Dim sjisEnc As Encoding
Dim str As String
Dim i as Integer

sjisEnc = sjisEnc.GetEncoding("Shift_JIS")
BytesA = sjisEnc.GetBytes(strString)
For i = 0 To 10
    BytesWK(i) = BytesA(i)
Next i

str = sjisEnc.GetString(BytesWK)

のようにバイト配列の値をループさせて
任意のバイト数だけ取得したいのですが
をデバックすると
よくわからないのですがstrの値が
str="12345"ではなく
str="12345
と"がついていない状態になり正しいString型では
なくなっているようなのですが
これはどういったことが原因なのでしょうか?

編集 削除
特攻隊長まるるう  2004-04-06 12:07:58  No: 112665  IP: [192.*.*.*]

これなら分かるんじゃない?
[VB.NET]
        Dim strString As String = "1234567890"
        Dim BytesA() As Byte
        Dim BytesWK() As Byte
        Dim sjisEnc As System.Text.Encoding
        Dim str As String
        Dim i As Integer

        sjisEnc = sjisEnc.GetEncoding("Shift_JIS")
        BytesA = sjisEnc.GetBytes(strString)
        ReDim BytesWK(UBound(BytesA, 1))
        For i = 0 To UBound(BytesA, 1)
            BytesWK(i) = BytesA(i)
        Next i

        str = sjisEnc.GetString(BytesWK)

編集 削除
特攻隊長まるるう  2004-04-06 12:40:37  No: 112666  IP: [192.*.*.*]

あ、ちゃうちゃう(汗)間違いです。

編集 削除
特攻隊長まるるう  2004-04-06 12:55:48  No: 112667  IP: [192.*.*.*]

Dim strString As String = "1234567890"
        Dim BytesA() As Byte
        Dim BytesWK() As Byte
        Dim sjisEnc As System.Text.Encoding
        Dim str As String
        Dim i, n As Integer
        n = 5

        sjisEnc = sjisEnc.GetEncoding("Shift_JIS")
        BytesA = sjisEnc.GetBytes(strString)
        ReDim BytesWK(n + 1)
        For i = 0 To n
            BytesWK(i) = BytesA(i)
        Next i
        BytesWK(n + 1) = AscW(10)    ' 多分これじゃ魔界の仮面弁士さんに怒られるw
        ReDim Preserve BytesWK(n)
        str = sjisEnc.GetString(BytesWK)

…もうちょっとまともな処理を探して見ます...

編集 削除
シル  2004-04-06 13:06:48  No: 112668  IP: [192.*.*.*]

特攻隊長まるるう
サンプルソースどうもありがとうございます。
「・・・怒られるw」というコメントまでコピーさせて頂きました^^
ReDimの意味も分かってない初心者なので
動かして見て色々勉強してみます。

編集 削除
シル  2004-04-06 13:07:30  No: 112669  IP: [192.*.*.*]

特攻隊長まるるう様
敬称を略してしまいました。
すいません。。。

編集 削除
シル  2004-04-06 13:38:08  No: 112670  IP: [192.*.*.*]

動作させてみたのですが
BytesWK(n + 1) = AscW(10) 
はどういう処理なのかと疑問に思って
とりあえずコメントにして動かしてみましたら
結果は同じだったです。
ポイントは
ReDim BytesWK(n + 1)
ReDim Preserve BytesWK(n)
の2点のようなのでこれについてちょっと勉強してみます。
どうもありがとうございました。

編集 削除
特攻隊長まるるう  2004-04-06 13:49:46  No: 112671  IP: [192.*.*.*]

いや、とりあえずのぐだぐだなコードですので…
魔界の仮面弁士さんにフォローをお願いしたく…すみません。
ちょっとだけマシ(…だと思う)コードです。
        Dim strString As String = "1123漢r字4567890"
        Dim BytesA() As Byte
        Dim BytesWK() As Byte
        Dim sjisEnc As System.text.Encoding
        Dim d As System.text.Decoder = System.Text.Encoding.UTF8.GetDecoder()
        Dim chars(Len(strString)) As Char
        Dim str As String
        Dim i, n As Integer
        n = 6

        sjisEnc = sjisEnc.GetEncoding("Shift_JIS")
        BytesA = sjisEnc.GetBytes(strString)
        ReDim BytesWK(n)
        For i = 0 To n
            BytesWK(i) = BytesA(i)
        Next i
        Dim charLen As Integer = d.GetChars(BytesWK, 0, BytesWK.Length, chars, 0)
        str = sjisEnc.GetString(BytesWK)

編集 削除
特攻隊長まるるう  2004-04-07 10:21:49  No: 112672  IP: [192.*.*.*]

最終的にこんな感じ。要するに文字として完結してないゴミがあったんですけど、
Visual Basic .NET のすべての文字列は Unicode で、MidB とかはサポートされて
なかったですね。 String にしてからの修正操作が見つかりませんでした。
[VB.NET]
        Dim strString As String = "1123漢r字4567890"
        Dim BytesA() As Byte
        Dim BytesWK() As Byte
        Dim sjisEnc As System.text.Encoding
        Dim str As String
        Dim i, n As Integer
        n = 15 ' 切り取りたいバイト数
        ' この時点で strString の文字の区切りと合ってない場合に修正しても
        'いいと思います。

        sjisEnc = sjisEnc.GetEncoding("Shift_JIS")
        BytesA = sjisEnc.GetBytes(strString)
        ReDim BytesWK(n - 1)
        For i = 0 To n - 1
            BytesWK(i) = BytesA(i)
        Next i

        i = UBound(BytesWK, 1)
        ' ↓ここの条件はコードページを基に修正してください。
        If BytesWK(i) = 130 _
        Or BytesWK(i) < 0 _
        Or BytesWK(i) < 0 Then
            ReDim Preserve BytesWK(i - 1)
        End If

        str = sjisEnc.GetString(BytesWK)

        'str = str & "Dummy" ' 最後に"が付いてない状態だとこの処理がうまくいかないです。

編集 削除
特攻隊長まるるう  2004-04-07 10:38:07  No: 112673  IP: [192.*.*.*]

[参考]全角と半角を判断する
http://www.sugi-family.net/papanvb/vbnet_tips.asp?cate=10&tips=10001

編集 削除
特攻隊長まるるう  2004-04-07 11:03:49  No: 112674  IP: [192.*.*.*]

たびたびスイマセン。これでホントの最終。
[VB.NET]
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim strString As String = "1123漢r字4567890"
        Dim BytesA() As Byte
        Dim BytesWK() As Byte
        Dim sjisEnc As System.text.Encoding
        Dim str As String
        Dim i, n As Integer
        n = 500 ' 切り取りたいバイト数
        n = KugiriCheck(strString, n)

        sjisEnc = sjisEnc.GetEncoding("Shift_JIS")
        BytesA = sjisEnc.GetBytes(strString)
        ReDim BytesWK(n - 1)
        For i = 0 To n - 1
            BytesWK(i) = BytesA(i)
        Next i

        i = UBound(BytesWK, 1)

        str = sjisEnc.GetString(BytesWK)

        'str = str & "Dummy" ' 最後に"が付いてないとこの処理がうまくいかないです。

    End Sub

    Private Function KugiriCheck(ByVal TextX As String, ByVal ByteLength As Integer) As Integer
        Dim i, intCheck, intReturn, intStep As Integer

        If ByteLength <= 0 Then Return 0

        For i = 1 To Len(TextX)
            intCheck = Asc(Mid(TextX, i, 1))
            If intCheck < 0 Or intCheck > 255 Then
                intStep = 2
            Else
                intStep = 1
            End If
            intReturn = intReturn + intStep

            If ByteLength = intReturn Then
                Return intReturn
            ElseIf ByteLength < intReturn Then
                Return intReturn - intStep
            End If
        Next

        Return intReturn
    End Function

編集 削除
シル  2004-04-07 11:20:04  No: 112675  IP: [192.*.*.*]

まるるう様
ありがとうございます。
配列の再割り当てというのが今までになかった
知識だったのでよくわかりませんでした。
またお世話になってしまうことがあるかも
しれませんがその時はよろしくお願いします。

編集 削除