文字列の中の、一部分の文字列を返します。
渡辺注:
(1). Shift_JIS のソース・コード(.bas ファイル)で、Shift_JIS の全角半角を、扱うことができる、KMid を追加しています。
(2). 日本語 Windows の、コマンドプロンプトの標準の「ラスターフォント(Raster font ビットマップ・フォント)」で、ユニコード文字列を Print 表示させると、全角文字列の右半分が欠落します。
ユニコード のソース・コード(.bas ファイル)で、WString の全角文字の Print を補助する、Expand を追加しています。
構文:
用法:
result = Mid [$]
( str , start [, n ] )
パラメタ:
str
元になる文字列
start
抽出元の文字列 str の中での、抽出する文字列の開始位置。
最初の文字は位置1で開始します。
n
抽出する文字列の文字数。
記述:
str で指定した文字列の start 以下の文字列を返します。
str が空ならば、ヌル文字 (" " ) を返します。
start <= 0 または start > len(str ) ならば、ヌル文字 (" " ) を返します。
Mid で、抽出する文字数を指定しないときは、残っている文字のすべてを返します。
抽出する文字数を指定しても、 n < 0 か n >= len(str ) なら、残っている文字のすべてを返します。
例:
Print Mid
( "abcdefg" , 3 , 2 )
Print Mid
( "abcdefg" , 3 )
Print Mid
( "abcdefg" , 2 , 1 )
Sleep
出力結果は下のようになります:
英数字と2バイトの日本語が混在する場合の処理例です。
参考:
ASCII 文字コード表
例 1:ソース・コード(.bas ファイル)は、Shift_JIS で保存
Dim As String mojiretsu
Dim As Integer mojisu
Dim As Integer i
Dim As Integer cCode
Declare Function KLen (mojiretsu As String) As Integer
Declare Function KMid (mojiretsu As String, start As Integer, mojisu As Integer) As String
Width 60, 30 '横幅を60桁に狭めます
mojiretsu="、-K2011年11月03日(曜日Thur.)"
mojisu=Len (mojiretsu)
Print mojiretsu
Print "文字数= ";mojisu
For i=1 to mojisu
cCode = Asc (Mid(mojiretsu, i, 1))
If cCode >= 129 And cCode <= 255 Then 'コードが2バイト文字の範囲なら
Print i,Mid(mojiretsu,i,2),Asc(Mid(mojiretsu,i,1)),"2バイト"
i = i + 1
Else
Print i,Mid(mojiretsu,i,1),Asc(Mid(mojiretsu,i,1)),"1バイト"
End If
Next i
Print "何かキーを押して下さい。"
Sleep
Print mojiretsu
mojisu=KLen (mojiretsu)
Print "文字数= ";mojisu
For i=1 to mojisu
Print i,KMid (mojiretsu,i,1)
Next i
Print "何かキーを押して下さい。"
Sleep
End
Function KMid (mojiretsu As String, start As Integer, mojisu As Integer) As String
Dim inS As Integer
Dim inN As Integer
Dim cCode As Integer
Dim Counter As Integer
Dim Modori As Integer
Counter = 0
inS = 0
While Counter < start
Modori = 1
inS = inS + 1
cCode = Asc(Mid(mojiretsu, inS, 1))
If (cCode >= &h81 And cCode <= &h9F) Or (cCode >= &hE0 And cCode <= &hFF) Then 'コードがSJIS2バイト文字の範囲なら
inS = inS + 1
Modori = 2
End If
Counter = Counter + 1
Wend
Counter = 0
inN = 0
While Counter < mojisu
inN = inN + 1
cCode = Asc(Mid(mojiretsu, inS - Modori + inN, 1))
If (cCode >= &h81 And cCode <= &h9F) Or (cCode >= &hE0 And cCode <= &hFF) Then 'コードがSJIS2バイト文字の範囲なら
inN = inN + 1
End If
Counter = Counter + 1
Wend
KMid = Mid (mojiretsu,inS - Modori + 1 ,inN)
End Function
Function KLen (mojiretsu As String) As Integer
Dim i As Integer
Dim cCode As Integer
Dim Result As Integer
Result = 0
For i = 1 To Len(mojiretsu)
cCode = Asc(Mid(mojiretsu, i, 1))
If (cCode >= &h81 And cCode <= &h9F) Or (cCode >= &hE0 And cCode <= &hFF) Then 'コードがSJIS2バイト文字の範囲なら
i = i + 1
End If
Result = Result + 1
Next i
KLen = Result
End Function
例 2:ソース・コード(.bas ファイル)は、ShiftJISでも UNICODE でも同じ結果!
'MidWStringShiftJIS.bas
'10進、16進文字コードin HTMLユニコード
'http://code.cside.com/3rdpage/jp/unicode/converter.html
'ユニコード表(10進表示)
'https://www.tamasoft.co.jp/ja/general-info/unicode-decimal.html
'Unicode キャラクター図鑑
'https://unicode-table.com/jp/
Dim mojiretsu As WString *1000
Dim As Integer mojisu
Dim As Integer i
Width 60, 30 '横幅を60桁に狭めます
mojiretsu="、-K2022年04月29日(曜日Fri.)"
mojisu=Len (mojiretsu)
Print mojiretsu
Print "文字数= ";mojisu
For i=1 to mojisu
Print i,Mid(mojiretsu,i,1),Asc(Mid(mojiretsu,i,1))
Next i
Print "何かキー入力で終了します。"
Sleep
実行画面で文字表示巾を広げるユーザ関数
Declare Function Expand(s As WString) as WString Ptr
Print *Expand("文字")
Function Expand (s As WString) as WString Ptr
Dim buf As WString Ptr
Dim i As Integer
buf = Allocate ((Len(s) * 2) * SizeOf (WString))
*buf = s
For i = 1 To Len(s)
If Asc(Mid(s, i, 1)) > 256 Then '全角文字の場合
*buf = *buf & Space(1)
End If
Next
Expand = buf
End Function
注:日本語 Windows 標準設定の、コマンド プロンプトの「ラスターフォント(Raster font ビットマップ・フォント)」では、Print で、ユニコードの文字を表示しようとすると、半角ベースの幅しか確保しません。このため、全角の文字を含む文字列を表示すると、右端が欠落します。
上の例のコードでは、2ちゃんねるの「デフォルトの名無し」さんのアイデアを拝借して、全角文字の文字数だけ、空白を、
Space で追加する、ユーザ定義関数
「Expand」 を使って、表示させる幅をかせいでいます。
コマンド プロンプトのタイトルバーを右クリックしてプロパティを表示させて、右画面のように、フォントを、「MS ゴシック」に変更すれば、プログラムで細工しなくても、素の print で全角文字列を表示できます。
これも、2ちゃんねるの、別の?「デフォルトの名無し」さんに教えていただきました。
追記:WString 型は、固定長のため、引数として関数に渡すことはできますが、WString 型の戻り値は、Ptrでしか返せません。
このため、上のユーザ定義関数
「Expand」 は、ポインターを使っています。
ポインターを使うために、メモリに
Allocate したデータは、必ず セットで
Deallocate する必要があります。そうしないと、メモリ・リークの恐れがあります。
このため、
「Expand」 の正しい使い方は、面倒ですが、下のようにするのが正解です。
Dim Japanese As WString * 100
Dim mojisu As Integer
Dim ResultPt As WString Ptr ' 格納するポインタ
Declare Function Expand(s As WString) as WString Ptr
ResultPt = Expand("今日は、世界! hello world!") ' アドレスを格納
Print *ResultPt ' そのアドレスにある値を表示
Deallocate (ResultPt) ' ResultPtが指し示しているアドレスに入っている値を開放
ResultPt = 0 ' ポインタに0を与えてポインタからアドレスを抹消
Japanese="今日は、世界! hello world!"
ResultPt = Expand(Japanese) ' アドレスを格納
Print *ResultPt ; Len(Japanese) ' そのアドレスにある値を表示
Print *ResultPt , Len(Japanese) ' そのアドレスにある値を表示
Print *ResultPt & *ResultPt ' そのアドレスにある値を表示(なぜか & の右が表示されない)
Print Len(Japanese) & *ResultPt & Len(Japanese) ' そのアドレスにある値を表示(なぜか & の右が表示されない)
Deallocate (ResultPt) ' ResultPtが指し示しているアドレスに入っている値を開放
ResultPt = 0 ' ポインタに0を与えてポインタからアドレスを抹消
ResultPt = Expand("何かキーを押して下さい。") ' アドレスを格納
Print *ResultPt ' そのアドレスにある値を表示
Deallocate (ResultPt) ' ResultPtが指し示しているアドレスに入っている値を開放
ResultPt = 0 ' ポインタに0を与えてポインタからアドレスを抹消
Sleep
ユニコードの例:
渡辺 注:どのマシン上でも、すべてのユニコード文字を見せることができる、というわけではありません。利用できる文字は、実行画面(コンソール)で現在使用中のフォントに依存します。
Wiki:
code rendered this way to allow display of the Unicode characters.
ユニコード文字を表示できるようにするために与えられたコード。
Dim textA
As wstring * 80
Dim textB
As WString * 80
Declare Function Expand(s As WString) as WString Ptr
textA =
"Привет, мир!"
textB =
"Привет,мир!"
Print " " ,*Expand(textA)
'表示結果 "Привет, мир!"
Print "mid(textA, 6, 4)" , *Expand(
Mid (textA, 6, 4))
' "т, м"
Print "mid(textA, 6, 5)" , *Expand(
mid (textA, 6, 5))
' "т, ми"
Print "mid(textA, 6, 6)" , *Expand(
mid (textA, 6, 6))
' "т, мир"
Print "mid(textA, 6, 7)" , *Expand(
mid (textA, 6, 7))
' "т, мир!"
Print "mid(textA, 6) " , *Expand(
mid (textA, 6))
'т, мир!"
Print
Print " " ,*Expand(textB)
'表示結果 "Привет,мир!"
Print "mid(textB, 6, 4)" , *Expand(
mid (textB, 6, 4))
' "т,ми"
Print "mid(textB, 6, 5)" , *Expand(
mid (textB, 6, 5))
' "т,мир"
Print "mid(textB, 6, 6)" , *Expand(
mid (textB, 6, 6))
' "т,мир!"
Print "mid(textB, 6) " , *Expand(
mid (textB, 6))
'т,мир!"
Sleep
Function
Expand (s As WString) as WString Ptr
Dim buf As WString Ptr
Dim i As Integer
buf =
Allocate ((Len(s) * 2) *
SizeOf (WString))
*buf = s
For i = 1 To Len(s)
If Asc(Mid(s, i, 1)) > 256 Then '全角文字の場合
*buf = *buf & Space(1)
End If
Next
Expand = buf
End Function
プラットホーム差:
DOSは、Mid のワイド文字型の文字バージョンを扱えません。
方言差:
QBからの違い:
参照:
文字コード判定のサンプル(VB6)
http://homepage2.nifty.com/nonnon/SoftSample/SampleModJUDG.html
文字列関数
http://afsoft.jp/program/p07n.html