FreeBASIC マニュアルのトップに戻る

FreeBASIC Encoding ShiftJIS

目次→実行時ライブラリー参考→ファイル入出力関連→文字を符号化→ENCODING←オリジナル・ページ

ENCODING(付録) ShiftJIS 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい


 渡辺注:日本語(全角)文字列の文字コードの ShiftJIS ⇔ UNICODE(utf-16) 変換方法を紹介するために、このページを挿入しています。

 別に、Window9 の AsciiToUtf と UtfToAscii を使ったバージョン もあります。


 下の例は、文字コードの ShiftJIS のテキスト・ファイルを読み込みこんで、UNICODE(utf-16) に変換して、別名で、UNICODE(utf-16) のテキスト・ファイルとして保存します。
 そして、このUNICODE(utf-16) のテキスト・ファイルを読み込んで、確認のため、再度、別名で、ShiftJIS のテキスト・ファイルとして書き出します。
 最初に読み込んだ、ShiftJIS のテキスト・ファイルと、最後に書き出した ShiftJIS のテキスト・ファイルを比較して、差異の無いことを確認して下さい。
 下の例は、プログラムのコード中の文字(直定数)を使っていないので、このプログラムを、★UNICODE(utf-16)★で保存しても、 ★ShiftJIS★で保存しても、同じ働きをします。

 対象のテキスト・ファイルを選択するために、ファイルを開くダイアログを使っています。

'' EncodingAscii2Utf16window9
'' このプログラム例は、以下の動作をします
'' 1) Ascii(日本語) コード化で、テキスト・ファイルを読み込みます。
'' 2) utf-16 コード化で、文字列をファイルに書きます。
'' 3) utf-16 ファイルからテキストを読み返します。
'' 4) 最初に読み込んだファイルと照合できるように Ascii(日本語) コード化で、ファイルに書きます。
''
'' 変換後のファイルは、同じフォルダに別名で保存されます。
'' WString を使っているため、全角文字をファイルに書き込むことができます。
'' ファイルを開くダイアログは、Window9 ライブラリを使っています。
'' http://users.freebasic-portal.de/freebasicru/window9lib/window9.html

Dim As Single t1,t2
Dim FullPass As String  '対象ファイルのフルパス  
Dim fName As String     '★拡張子無しのファイル名
Dim extension As String '★拡張子部分(例:.txt)


'**************** ファイルを開くダイアログ部分に Window9 を使う *******************
#Include "window9.bi"
'******************* Window9 のファイルを開くダイアログを使う *********************
   ''FileOpen
   FullPass = OpenFileRequester("変換するファイルを指定","C:\test\","テキストファイル(*.txt;*.csv;*.htm*)"_
+Chr(0)+"*.txt;*.csv;*.htm*"+Chr(0)+"全てのファイル(*.*)"+Chr(0)+"*.*"+Chr(0))

   fName = Left(FullPass,InStrRev(FullPass,".") -1)  '対象のテキストファイルのフルパスの、拡張子無し部分
   extension = Right(FullPass,Len(FullPass) - InStrRev(FullPass,".") +1) '対象テキストファイルのドット付き拡張子部分
'******************* Window9 のファイルを開くダイアログ終わり *********************

t1 = Timer

Scope
   Dim s As WString *3000
  
   '' Ascii(日本語) コードで、入力のためのファイルを開きます。
   Open fName & extension For Input Encoding "ascii" As #1
   '' ASCII文字列は、そのまま読み込まれます。
  
   '' utf-16 コードで出力するためのファイルを開きます。
   Open fName & "Utf16" & extension  For Output Encoding "utf-16" As #2
   '' ASCII文字列は、utf-16に変換されます。
  
   Do Until EOF(1)               '' ファイルの端に達するまで、繰り返します。
      Line Input #1, s           '' テキストの行を読みます ...
      Print #2, s                '' ... そして、ファイルに出力します。
   Loop
  
   Close #1
   Close #2
End Scope
''


Scope
   Dim s As WString *3000
   Dim s2 As String
  
   '' utf-16 コードで入力するためのファイルを開きます。
   Open fName & "Utf16" & extension  For Input Encoding "utf-16" As #1
   '' utf-16文字列は、そのまま読み込まれます。

   '' Ascii(日本語) コードで、出力のためのファイルを開きます。
   Open fName & "Ascii" & extension For Output Encoding "ascii" As #2
   '' utf-16文字列は、ASCII文字列に変換されます。
    
   Do Until EOF(1)               '' ファイルの端に達するまで、繰り返します。
      Line Input #1, s           '' テキストの行を読みます ...
      'Print s
      s2 = s                     '' 何故かこうすると、文字列の欠落が防げます。
      Print #2, s2               '' ... そして、ファイルに出力します。
   Loop
  
   Close #1
   Close #2
End Scope

t2 = Timer

Print
Print
Print "変換所要秒数 = ";t2 - t1
Print "何かキー入力で終了します"
Sleep



 下の例は、青空文庫のルビ表記を、html の「ルビタグ」に変換するものです。
 文字処理関数を使うため、途中で UNICODE に変換して処理しています。
 Shift-JIS のままで処理するバージョンもあります。
変換前のテキスト(Shift-JIS の html) は、ファイル名を、「mae.html」 として、C ドライブの test フォルダに登録します。
変換後のテキスト(Shift-JIS の html) は、同一フォルダに、「ato_Riby.html」というファイル名で作られます。
 このプログラムは、ソース中の文字定数を「UNICODE」として扱いますが、コード(.bas ファイル)は、Shift-JIS で保存しても機能します。
サンプルのテキスト・ファイルと、ソースは、ここでダウンロードできます。→RubyTagForFB_UNICODE.zip

 「UNICODE」として扱うために、わざわざ中間ファイルに書き出さなくても WStr 関数で変換できることが分かりまし。(^^ゞ
' ★このプログラム・コードは、Shift-JIS で保存しても、UNICODE で保存しても同じ出力を得られます。★

Dim InputFile As String
Dim OutputFile As String
Dim Utf16File As String
Dim InputLine As String
Dim InputLineW As WString * 10000
Dim OutputLineW As WString * 10000
Dim OutputLine As String


Dim bodyFlag As Integer
Dim ProcessingLineCounter As Integer

Dim StartTime As Long
Dim EndTime As Long

Declare Sub HonbunSyori (OutputLineW As WString, InputLineW As WString)


InputFile="c:\test\mae.html"
Utf16File="c:\test\maeUtf16.html"
OutputFile="c:\test\ato_Ruby.html"

Print Time
StartTime=Val(Left(Time,2))*3600+Val(Mid(Time,4,2))*60+Val(Right(Time,2))

'************ ShiftJIS→UNICODE ********************
Scope
   Dim s As WString *3000
  
   '' Ascii(日本語) コードで、入力のためのファイルを開きます。
   Open InputFile For Input Encoding "ascii" As #1
   '' ASCII文字列は、そのまま読み込まれます。
  
   '' utf-16 コードで出力するためのファイルを開きます。
   Open Utf16File  For Output Encoding "utf-16" As #2
   '' ASCII文字列は、utf-16に変換されます。
  
   Do Until EOF(1)               '' ファイルの端に達するまで、繰り返します。
      Line Input #1, s           '' テキストの行を読みます ...
      Print #2, s                '' ... そして、ファイルに出力します。
   Loop
  
   Close #1
   Close #2
End Scope

'********************************
'ファイルのオープン。
bodyFlag = 0
ProcessingLineCounter = 0

Open Utf16File For Input  Encoding "utf-16" As #1
Open OutputFile For Output As #2
'*************データの読み込み***********
While (EOF(1) = 0)
    ProcessingLineCounter = ProcessingLineCounter + 1
    Line Input #1, InputLineW
    
    OutputLineW = InputLineW
    
    If InStr (InputLineW, "</body>") > 0 Then
        bodyFlag = 0
    End If
    
    If bodyFlag = 1 Then
'       本文処理  '★★★★★★★★★
'        Print InputLineW & Space(Len(InputLineW))
        HonbunSyori (OutputLineW , InputLineW )
    End If
      
    If InStr (InputLineW, "<body") > 0 Then
        bodyFlag = 1
    End If
    
'  'ワイドから、日本語マルチバイトに変換
    OutputLine = OutputLineW
'  'そして、出力します。
    Print #2, OutputLine
    
    OutputLine = ""
'    OutputLineF = ""
    InputLineW = ""
    OutputLineW = ""
    
    If (ProcessingLineCounter Mod 10) = 0 Then
	    Print ProcessingLineCounter , " 行目を読込み" & Space(Len(" 行目を読込み"))
    End If
       
Wend

'**************終了処理*********************
Print ProcessingLineCounter , " 最終行まで読込み完了" & Space(Len(" 最終行まで読込み完了"))
Close #1: Close #2

	Print Time
EndTime = Val(Left(Time,2))*3600+Val(Mid(Time,4,2))*60+Val(Right(Time,2))
Print "処理が終了しました。" & Space(Len("処理が終了しました。"))
Print "処理時間は、" & Space(Len("処理時間は、"));EndTime-StartTime; "秒でした。" & Space(Len("秒でした。"))
Print "何かキーを押して下さい。" & Space(Len("何かキーを押して下さい。"))
Sleep


'**************本文処理*********************
Sub HonbunSyori (OutputLineW As WString, InputLineW As WString)

	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
	
    OutputLineW = ""
    BackgroundNumber = 0
    KanjiNumber = 0
    RubyNumber = 0
    KanjiFlag = 0
    RubyFlag = 0
    BackgroundFlag = 1               '行末に > がない場合を考慮
    
    InputLineNumber = Len(InputLineW)
    
    For Figure = InputLineNumber To 1 Step -1        '文字列の後ろから、処理していく点が、ミソ
    	
        If Mid(InputLineW, 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 Mid(InputLineW, Figure, 1) = "》" Then  'ルビの開始 '★★2006年6月5日追加
        
			'#Ifdef __FB_WIN32__
			'	messagebox(NULL, InputLineW ,"",MB_OK)
			'#EndIf
        
            OutputLineW = "</rt><rp>)</rp></ruby><ruby><rb>" & Mid(InputLineW, Figure + 1, KanjiNumber - 1) & OutputLineW
            
            KanjiNumber = 0
            KanjiFlag = 0
            
            BackgroundNumber = 0
            RubyNumber = 0     '前回のRubyNumberをリセット
            BackgroundFlag = 0
            RubyFlag = 1
        
        ElseIf Mid (InputLineW, Figure, 1) = "》" Then               'ルビの開始
        	
			'#Ifdef __FB_WIN32__
			'	messagebox(NULL, InputLineW ,"",MB_OK)
			'#EndIf
        	
            OutputLineW = "</rt><rp>)</rp></ruby>" & Mid(InputLineW, Figure + 1, BackgroundNumber - 1) & OutputLineW
            BackgroundNumber = 0
            RubyNumber = 0     '前回のRubyNumberをリセット
            BackgroundFlag = 0
            RubyFlag = 1
            
        ElseIf Mid(InputLineW, Figure, 1) = "《" Then         'ルビの終了
            OutputLineW = "</rb><rp>(</rp><rt>" & Mid(InputLineW, Figure + 1, RubyNumber - 1) & OutputLineW
            KanjiNumber = 0     '前回のKanjiNumberをリセット
            RubyFlag = 0
            KanjiFlag = 1
            
        ElseIf KanjiFlag = 1 And (Mid(InputLineW, Figure, 1) = "|" _
        Or Mid(InputLineW, Figure, 1) = "│") Then      '"|"JIS 8162は記号の縦線。"│"JIS 84A0は罫線の縦線
            '★ガリバー対応★★★★2006年6月5日追加
            OutputLineW = "<ruby><rb>" & Mid(InputLineW, Figure + 1, KanjiNumber - 1) & OutputLineW
            KanjiNumber = 0
            KanjiFlag = 0
            BackgroundFlag = 1
            
        ElseIf KanjiFlag = 1 And (Mid(InputLineW, Figure, 1) = "(" _
        Or Mid(InputLineW, Figure, 1) = ")") Then       '(例)1円山応挙《まるやまおうきょ》
            '★夜明け前対応★★★★2006年6月6日追加
            OutputLineW = "<ruby><rb>" & Mid(InputLineW, Figure + 1, KanjiNumber - 1) & OutputLineW
            KanjiNumber = 0
            KanjiFlag = 0
            BackgroundFlag = 1
            BackgroundNumber = 1    'Backgroundのところまで侵食したため戻す
            
'        ElseIf Mid(InputLineW, Figure + 1, 1) >= "亜" And KanjiNumber > 1 _
'        And Mid(InputLineW, Figure, 1) < "亜" Then  '★つぐみ対応★★★★2006年6月5日追加
        
        ElseIf Mid(InputLineW, Figure + 1, 1) > "ヶ" And KanjiNumber > 1 _
        And Mid(InputLineW, Figure, 1) <= "ヶ" Then  '★大丈夫対応★★★★2006年6月5日追加
            OutputLineW = "<ruby><rb>" & Mid(InputLineW, Figure + 1, KanjiNumber - 1) & OutputLineW
            KanjiNumber = 0
            KanjiFlag = 0
            BackgroundFlag = 1
            BackgroundNumber = 1    'Backgroundのところまで侵食したため戻す
            
        ElseIf RubyNumber > 0 And KanjiNumber = RubyNumber Then
            OutputLineW = "<ruby><rb>" & Mid(InputLineW, Figure + 1, KanjiNumber - 1) & OutputLineW
            KanjiNumber = 0
            KanjiFlag = 0
            BackgroundFlag = 1
            BackgroundNumber = 1    'Backgroundのところまで侵食したため戻す

        ElseIf KanjiFlag = 1 And Figure = 1 Then    '行頭のKanji
            '★夜明け前対応★★★★2006年6月8日追加
            OutputLineW = "<ruby><rb>" & Mid(InputLineW, Figure, KanjiNumber) & OutputLineW
            KanjiNumber = 0
            KanjiFlag = 0

        End If
    
'       If ProcessingLineCounter = 71 Then Stop  '●●▲●●
    
    Next Figure
    
    If BackgroundFlag = 1 And BackgroundNumber > 0 Then
        OutputLineW = Mid(InputLineW, Figure + 1, BackgroundNumber) & OutputLineW
    End If
    
End Sub

参照:
ファイル入出力関連に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2022-04-26
日本語著作者:WATANABE Makoto

ホームページのトップに戻る

表示-非営利-継承