VB.NETの文字列はユニコードUTF-16(2バイト)が使用されます。
半角文字も全角文字も2バイトで表現されるので、
“ストリング” と言う文字列が10バイトと言うのは分かりますが、
“aaaaa” と言う半角文字列も10バイト使用されるのです。
しかし、業務上の理由などで、
文字列をバイト単位で処理したい場合があると思いますので、
その方法について説明していきたいと思います。
文字列をバイト単位で処理してくれる関数は
VB.NETには無いようなので、自作する事になります。
(VB6.0ではLeftB, MidB, RightB関数があったようです。)
その関数を疑似的にVB.NETで作ってみます。
まず、文字列をバイト単位で扱いたいときは、
文字コードをユニコードからShift-JISへ変換します。
そうすると、
半角文字が1バイト、全角文字が2バイトの混合文字列に変換されます。
その状態でバイト単位の文字列処理を行います。
サンプルを作ってみましたので、
アレンジして使ってください。
Sub Main()
Dim str As String = "文字列aaa終端"
'左端から??バイトを取得
'"文字列aaa終端"
Console.WriteLine(myLeftB(str, 1)) 'エラー
Console.WriteLine(myLeftB(str, 2)) '文
Console.WriteLine(myLeftB(str, 3)) 'エラー
Console.WriteLine(myLeftB(str, 4)) '文字
Console.WriteLine(myLeftB(str, 7)) '文字列a
Console.WriteLine(myLeftB(str, 10)) 'エラー
Console.WriteLine(myLeftB(str, 11)) '文字列aaa終
Console.WriteLine()
'中間文字列を取得
'"文字列aaa終端"
Console.WriteLine(myMidB(str, 1, 2)) '文
Console.WriteLine(myMidB(str, 1, 3)) 'エラー
Console.WriteLine(myMidB(str, 1, 4)) '文字
Console.WriteLine(myMidB(str, 2, 3)) 'エラー
Console.WriteLine(myMidB(str, 7, 3)) 'aaa
Console.WriteLine(myMidB(str, 7, 4)) 'エラー
Console.WriteLine(myMidB(str, 10, 4)) '終端
Console.WriteLine(myMidB(str, 11, 3)) 'エラー
Console.WriteLine()
Console.WriteLine(myMidB(str, 3)) '字列aaa終端
Console.WriteLine(myMidB(str, 2)) 'エラー
Console.WriteLine(myMidB(str, 7)) 'aaa終端
Console.WriteLine()
'右端から??バイトを取得
'"文字列aaa終端"
Console.WriteLine(myRightB(str, 4)) '終端
Console.WriteLine(myRightB(str, 3)) 'エラー
Console.WriteLine(myRightB(str, 7)) 'aaa終端
Console.WriteLine(myRightB(str, 8)) 'エラー
End Sub
Function myLeftB(ByVal str As String, blen As Integer) As String
Dim Enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS")
Dim bStr As Byte() = Enc.GetBytes(str)
'マルチバイト情報を取得
Dim dic As New Dictionary(Of Integer, Integer)()
dic = makeDicMultibyteStringInfo(bStr)
'指定された数値のエラーチェック
'終わりのバイト位置が「マルチバイトの1バイト目」だったらエラー
If dic(blen) = 1 Then
Return "エラー"
Else
Return Enc.GetString(bStr, 0, blen)
End If
End Function
Function myMidB(ByVal str As String, iStart As Integer) As String
Dim Enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS")
Dim bStr As Byte() = Enc.GetBytes(str)
'マルチバイト情報を取得
Dim dic As New Dictionary(Of Integer, Integer)()
dic = makeDicMultibyteStringInfo(bStr)
'指定された数値のエラーチェック
'始まりのバイト位置が「マルチバイトの2バイト目」だったらエラー
If dic(iStart) = 2 Then
Return "エラー"
End If
Return Enc.GetString(bStr, iStart - 1, bStr.Length - iStart + 1)
End Function
Function myMidB(ByVal str As String, iStart As Integer, blen As Integer) As String
Dim Enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS")
Dim bStr As Byte() = Enc.GetBytes(str)
'マルチバイト情報を取得
Dim dic As New Dictionary(Of Integer, Integer)()
dic = makeDicMultibyteStringInfo(bStr)
'指定された数値のエラーチェック
'始まりのバイト位置が「マルチバイトの2バイト目」だったらエラー
If dic(iStart) = 2 Then
Return "エラー"
End If
'終わりのバイト位置が「マルチバイトの1バイト目」だったらエラー
If dic(iStart + blen - 1) = 1 Then
Return "エラー"
End If
Return Enc.GetString(bStr, iStart - 1, blen)
End Function
Function myRightB(ByVal str As String, blen As Integer) As String
Dim Enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS")
Dim bStr As Byte() = Enc.GetBytes(str)
'マルチバイト情報を取得
Dim dic As New Dictionary(Of Integer, Integer)()
dic = makeDicMultibyteStringInfo(bStr)
'文字列aaa終端
'指定された数値のエラーチェック
'始まりのバイト位置が「マルチバイトの2バイト目」だったらエラー
If dic(bStr.Length - blen + 1) = 2 Then
Return "エラー"
End If
Return Enc.GetString(bStr, (bStr.Length - blen), blen)
End Function
Function makeDicMultibyteStringInfo(ByRef bStr As Byte()) As Object
Dim dic As New Dictionary(Of Integer, Integer)()
'全角文字の存在する場所(何バイト目か)を調べる
'1バイト目か、2バイト目かの情報を得ておく
Dim i As Integer = 0
While i < bStr.Length
If SJIS1stbyteCheck(bStr.GetValue(i)) = True Then
dic.Add(i + 1, 1) '全角1バイト目だったら1
dic.Add(i + 2, 2) '全角2バイト目だったら2
i = i + 2
Else
dic.Add(i + 1, 3) '半角だったら3
i = i + 1
End If
End While
Return dic
End Function
Function SJIS1stbyteCheck(ByVal b As Byte) As Boolean
If ((b >= &H81) AndAlso (b <= &H9F)) OrElse ((b >= &HE0) AndAlso (b <= &HFC)) Then
Return True
Else
Return False
End If
End Function