FreeBASIC KLEN KMID
目次 →実行時ライブラリー参考→文字列関数 →KLEN と KMID
KLEN
全角・半角も1文字扱いとして、変数の長さを返します。2バイト系文字1文字を1つの文字として考える事ができます。
渡辺注:Shift_JIS のソース・コード(.bas ファイル)で、Shift_JIS の全角半角を、扱うことができる、KLen を追加しています。
構文:
用法:
result = KLen
( variable )
パラメタ:
戻り値:
変数のサイズか、文字数で戻されます。
記述:
KLen は、変数の長さを、文字数で返します。
例 1:ソース・コード(.bas ファイル)は、Shift_JIS で保存
Dim Japanese As WString * 20
Declare Function
KLen (mojiretsu As String) As Integer
Japanese = "今日は、世界!"
Print Len ( "hello world" ) ,
KLen ( "hello world" )
'戻り値 "11" と "11"
Print Len ( Integer ) '戻り値 " 4"
Print Len ( "今日は、世界!"
) ,
KLen ( "今日は、世界!"
)
'戻り値 "14" と "7"
Print Len ( "今日は、world"
) ,
KLen ( "今日は、world"
)
'戻り値 "13" と "9"
Print Len ( Japanese
) ,
KLen ( Japanese
)
'戻り値 "7" と "7"
Print "何かキーを押して下さい。"
Sleep
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
'コードが2バイト文字の範囲なら
i = i + 1
End If
Result = Result + 1
Next i
KLen = Result
End Function
KMID
全角・半角も1文字扱いとして、文字列の中の、一部分の文字列を返します。2バイト系文字1文字を1つの文字として考える事ができます。
渡辺注:
Shift_JIS のソース・コード(.bas ファイル)で、Shift_JIS の全角半角を、扱うことができる、KMid を追加しています。
構文:
用法:
result = KMid
( str , start , n )
パラメタ:
str
元になる文字列
start
抽出元の文字列 str の中での、抽出する文字列の開始位置。
n
抽出する文字列の文字数。
記述:
str で指定した文字列の、start 以下の文字列を返します。
str が空ならば、ヌル文字 (" " ) を返します。
start <= 0 ならば、ヌル文字 (" " ) を返します。
抽出する文字数を指定しても、 n < 0 か n >= len(str ) なら、残っている文字のすべてを返します。
例 2:
英数字と2バイトの日本語が混在する場合の処理例です。
参考:ASCII 文字コード表
KLen KMid を使わない方法
ソース・コード(.bas ファイル)は、Shift_JIS で保存
' KLen KMid を使わない方法
Dim As String mojiretsu
Dim As Integer mojisu
Dim As Integer i
Dim As Integer cCode
Width 60, 30 '横幅を60桁に狭めます
mojiretsu= "、-K2009年10月04日(曜日Sun.)"
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
KLen KMid を使う方法(メインの部分がシンプルでしょう?)
ソース・コード(.bas ファイル)は、Shift_JIS で保存
#include "vbcompat.bi "
Dim As String mojiretsu
Dim As Integer mojisu
Dim As Integer i
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= "、-K2009年10月04日(曜日Sun.)"
mojisu= KLen (mojiretsu)
Print mojiretsu
Print "文字数= "; mojisu
For i=1 to mojisu
Print i,KMid (mojiretsu,i,1), Asc (KMid (mojiretsu,i,1)),
If Len(KMid (mojiretsu,i,1)) =1 Then
Print "1バイト"
Else
Print "2バイト"
End If
Next i
Print "何かキーを押して下さい。"
Print
Sleep
' おまけ:今日の日付を使って表示し直します。
Dim Date_Serial As Double = Now ()
Print "今日の日付シリアル値:" ; Date_Serial
mojiretsu= Format (Date_Serial, "yyyy年mm月dd日") & "(" & WeekdayName (Weekday (Date_Serial)) & ")"
Print mojiretsu
mojisu= KLen (mojiretsu)
Print "文字数= "; mojisu
For i=1 to mojisu
Print i, KMid (mojiretsu,i,1), Asc (KMid (mojiretsu,i,1)),
If Len(KMid (mojiretsu,i,1)) =1 Then
Print "1バイト"
Else
Print "2バイト"
End If
Next i
Print "何かキーを押して下さい。"
Sleep
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
例 3:
' 目的:青空文庫のルビ表記 を、html の「ルビタグ」に変換します。
' 変換前のテキスト(Shift-JIS の html) は、ファイル名を、「mae.html 」 として、C ドライブの temp フォルダに登録します。
' 変換後のテキスト(Shift-JIS の html) は、同一フォルダに、「ato_Riby.html」というファイル名で作られます。
ソース・コード(.bas ファイル)は、Shift_JIS で保存
サンプルのテキスト・ファイルと、ソースは、ここでダウンロードできます。→RubyTagForFB.zip
FreeBASIC の本来の関数だけを使った、UNICODE 版 も、お試し下さい。さすが、UNICODE 版は、圧倒的な速さで、5秒で処理が終わります。(^^ゞ
Dim InputFile As String
Dim OutputFile As String
Dim InputLine As String
Dim OutputLine As String
Dim bodyFlag As Integer
Dim ProcessingLineCounter As Integer
Dim StartTime As Long
Dim EndTime As Long
Declare Sub HonbunSyori (OutputLine As String, InputLine As String)
Declare Function KLen (mojiretsu As String) As Integer
Declare Function KMid (mojiretsu As String, start As Integer, mojisu As Integer) As String
' 目的:青空文庫のルビ表記を、html の「ルビタグ」に変換します。
' 変換前のテキスト(Shift-JIS の html) は、ファイル名を、「mae.html」 として、C ドライブの temp フォルダに登録します。
' 変換後のテキスト(Shift-JIS の html) は、同一フォルダに、「ato_Riby.html」というファイル名で作られます。
InputFile="c:\temp\mae.html"
OutputFile="c:\temp\ato_Ruby.html"
Print Time
StartTime=Val(Left(Time ,2))*3600+Val(Mid(Time ,4,2))*60+Val(Right(Time ,2))
'********************************
'ファイルのオープン。
bodyFlag = 0
ProcessingLineCounter = 0
Open InputFile For Input As #1
Open OutputFile For Output As #2
'*************データの読み込み***********
While (Eof(1) = 0)
ProcessingLineCounter = ProcessingLineCounter + 1
Line Input # 1, InputLine
OutputLine = InputLine
' If Trim(InputLine) = "</body>" Then
If InputLine = "</body>" Then
bodyFlag = 0
End If
If bodyFlag = 1 Then
' 本文処理 '★★★★★★★★★
HonbunSyori (OutputLine , InputLine )
End If
If Left(InputLine, 5) = "<body" Then
bodyFlag = 1
End If
Print # 2, OutputLine
If (ProcessingLineCounter Mod 10) = 0 Then
Print ProcessingLineCounter , " 行目を読込み"
End If
Wend
'**************終了処理*********************
Print ProcessingLineCounter , " 最終行まで読込み完了"
Close #1: Close #2
Print Time
EndTime = Val(Left(Time ,2))*3600+Val(Mid(Time ,4,2))*60+Val(Right(Time ,2))
Print "処理が終了しました。"
Print Using "処理時間は、###秒でした。";EndTime-StartTime
Print "処理が終了しました。何かキーを押して下さい。"
Sleep
Sub HonbunSyori (OutputLine As String, InputLine As String)
Dim InputLineNumber As Integer
Dim Figure As Integer
Dim BackgroundFlag As Integer
Dim RubyNumber As Integer
Dim KanjiFlag As Integer
Dim RubyFlag As Integer
Dim BackgroundNumber As Integer
Dim KanjiNumber As Integer
OutputLine = ""
BackgroundNumber = 0
KanjiNumber = 0
RubyNumber = 0
KanjiFlag = 0
RubyFlag = 0
BackgroundFlag = 1 '行末に > がない場合を考慮
InputLineNumber = KLen(InputLine)
For Figure = InputLineNumber To 1 Step -1 '文字列の後ろから、処理していく点が、ミソ
If KMid(InputLine, Figure, 1) = ">" Then 'タグ内
BackgroundFlag = 1
End If
If RubyFlag = 1 Then
RubyNumber = RubyNumber + 1 'ルビの文字数を数えている
ElseIf KanjiFlag = 1 Then
KanjiNumber = KanjiNumber + 1 '漢字の文字数を数えている
ElseIf BackgroundFlag = 1 Then
BackgroundNumber = BackgroundNumber + 1 'タグの文字数を数えている
End If
If KanjiFlag = 1 And KMid(InputLine, Figure, 1) = "》" Then '★★6月5日追加
'#Ifdef __FB_WIN32__
' messagebox(NULL, InputLine ,"",MB_OK)
'#EndIf
OutputLine = "</rt><rp>)</rp></ruby><ruby><rb>" & KMid(InputLine, Figure + 1, KanjiNumber - 1) & OutputLine
KanjiNumber = 0
KanjiFlag = 0
BackgroundNumber = 0
RubyNumber = 0 '前回のRubyNumberをリセット
BackgroundFlag = 0
RubyFlag = 1
ElseIf KMid (InputLine, Figure, 1) = "》" Then
'#Ifdef __FB_WIN32__
' messagebox(NULL, InputLine ,"",MB_OK)
'#EndIf
OutputLine = "</rt><rp>)</rp></ruby>" & KMid(InputLine, Figure + 1, BackgroundNumber - 1) & OutputLine
BackgroundNumber = 0
RubyNumber = 0 '前回のRubyNumberをリセット
BackgroundFlag = 0
RubyFlag = 1
ElseIf KMid(InputLine, Figure, 1) = "《" Then
OutputLine = "</rb><rp>(</rp><rt>" & KMid(InputLine, Figure + 1, RubyNumber - 1) & OutputLine
KanjiNumber = 0 '前回のKanjiNumberをリセット
RubyFlag = 0
KanjiFlag = 1
ElseIf KanjiFlag = 1 And (KMid(InputLine, Figure, 1) = "|" _
Or KMid(InputLine, Figure, 1) = "│") Then '"|"JIS 8162は記号の縦線。"│"JIS 84A0は罫線の縦線
'★ガリバー対応★★★★6月5日追加
OutputLine = "<ruby><rb>" & KMid(InputLine, Figure + 1, KanjiNumber - 1) & OutputLine
KanjiNumber = 0
KanjiFlag = 0
BackgroundFlag = 1
ElseIf KanjiFlag = 1 And (KMid(InputLine, Figure, 1) = "(" _
Or KMid(InputLine, Figure, 1) = ")") Then '(例)1円山応挙《まるやまおうきょ》
'★夜明け前対応★★★★6月6日追加
OutputLine = "<ruby><rb>" & KMid(InputLine, Figure + 1, KanjiNumber - 1) & OutputLine
KanjiNumber = 0
KanjiFlag = 0
BackgroundFlag = 1
BackgroundNumber = 1 'Backgroundのところまで侵食したため戻す
' ElseIf KMid(InputLine, Figure + 1, 1) >= "亜" And KanjiNumber > 1 _
' And KMid(InputLine, Figure, 1) < "亜" Then '★つぐみ対応★★★★6月5日追加
ElseIf KMid(InputLine, Figure + 1, 1) > "ヶ" And KanjiNumber > 1 _
And KMid(InputLine, Figure, 1) <= "ヶ" Then '★大丈夫対応★★★★6月5日追加
OutputLine = "<ruby><rb>" & KMid(InputLine, Figure + 1, KanjiNumber - 1) & OutputLine
KanjiNumber = 0
KanjiFlag = 0
BackgroundFlag = 1
BackgroundNumber = 1 'Backgroundのところまで侵食したため戻す
ElseIf RubyNumber > 0 And KanjiNumber = RubyNumber Then
OutputLine = "<ruby><rb>" & KMid(InputLine, Figure + 1, KanjiNumber - 1) & OutputLine
KanjiNumber = 0
KanjiFlag = 0
BackgroundFlag = 1
BackgroundNumber = 1 'Backgroundのところまで侵食したため戻す
ElseIf KanjiFlag = 1 And Figure = 1 Then '行頭のKanji
'★夜明け前対応★★★★6月8日追加
OutputLine = "<ruby><rb>" & KMid(InputLine, Figure, KanjiNumber) & OutputLine
KanjiNumber = 0
KanjiFlag = 0
End If
' If ProcessingLineCounter = 71 Then Stop '●●▲●●
Next Figure
If BackgroundFlag = 1 And BackgroundNumber > 0 Then
OutputLine = KMid(InputLine, Figure + 1, BackgroundNumber) & OutputLine
End If
End Sub
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
参照:
文字コード判定のサンプル(VB6)
http://nonsoft.la.coocan.jp/SoftSample/SampleModJUDG.html
文字コードを判別する
http://dobon.net/vb/dotnet/string/detectcode.html
文字列関数
http://afsoft.jp/program/p07n.html
ページ歴史:2016-09-16
作成:2011-12-16
日本語著作者:WATANABE Makoto