掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
SHIFT-JISコードに変換 (ID:32262)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
こんな感じです。 速度と可読性を重視して書きました。 もっと早くできると思いますが、 サンプルということなのでご了承ください。 あと、ネットを徘徊すればjis-sjis変換は結構見つけることができると思います。 今回はググッて最初にみつかった「とほほのwww入門」を参考にしました。 http://www.tohoho-web.com/wwwkanji.htm 実用レベルとは思いますが、 Mr.XRayさんの紹介するコードより高速かどうか検証はしていません。(多分この程度では勝てません。) unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} //漢字コードの変換 procedure ConvertISO_2022_JPtoShiftJIS(var c1,c2:byte); begin if (c1 mod 2)=1 then begin c1 := ((c1 + 1) div 2) + $70; c2 := c2 + $1f; end else begin c1 := (c1 div 2) + $70; c2 := c2 + $7d; end; if (c1 >= $a0) then c1 := c1 + $40; if (c2 >= $7f) then c2 := c2 + 1; end; function ISO_2022_JPtoShiftJIS(s:AnsiString; CRLF:Boolean):AnsiString; type TJisStyle = (jsNone,jsASCII,jsRoman,jsKana,jsOldKanji,jsNewKanji,jsOpKanji); var i,p,r,Len,skip:Integer; b1,b2: Byte; jStyle,jStyleConst:TJisStyle; begin { ISO_2022_JP(7bit JIS) 00-1F,7F 制御コード 1B 28 42 - ESC ( B - 20-7E ASCII 1B 28 4A - ESC ( J - 20-7E JISローマ字 1B 28 49 - ESC ( I - 21-5F JISカナ(半角カナ) 1B 24 40 - ESC $ @ - 21-7E 21-7E 旧JIS漢字 (1978) 1B 24 42 - ESC $ B - 21-7E 21-7E 新JIS漢字 (1983/1990) 1B 24 44 - ESC $ D - 21-7E 21-7E JIS補助漢字 SJIS 00-1F, 7F 制御コード 20-7E JISローマ字(ASCII) A1-DF JISカナ(半角カナ) 81-9F 40-7E JIS漢字 E0-EF 80-FC JIS漢字 改行コードの扱いについて ISO_2022_JPの改行は $0A ですがTStringListで読み込むと $0D$0A に補完されます。 } p:=1; skip:=0; Len := Length(s); //文字バッファーを一度に確保 //メモリーサイズ jis >= sjisだからjis分確保すれば問題ないはず。 //改行コードを変換を入れるときは適当に大きめにする。 //これは大きいほど処理が早くなるがその分無駄にメモリーを消費する場合がある。 //あらかじめ改行をカウントすれば適切なサイズを得ることができるが、 //今回は速度重視のため、文字走査を一回にするため敢えてカウントしていません。 if CRLF then Len:= Round(Len*1.5); SetLength(Result,Len); jStyleConst := jsASCII; for i := 1 to Len do //メインループ begin if skip = 0 then begin jStyle:=jsNone; //エスケープシーケンス判定 if i < Len-3 then if (byte(s[i]) = $1B) then begin if (byte(s[i+1]) = $28) then begin if (byte(s[i+2]) = $42) then jStyle:=jsASCII else if (byte(s[i+2]) = $4A) then jStyle:=jsRoman else if (byte(s[i+2]) = $49) then jStyle:=jsKana; end else if (byte(s[i+1]) = $24) then begin if (byte(s[i+2]) = $40) then jStyle:=jsOldKanji else if (byte(s[i+2]) = $42) then jStyle:=jsNewKanji else if (byte(s[i+2]) = $44) then jStyle:=jsOpKanji; end; end; if jStyle <> jsNone then begin skip:=3; jStyleConst:=jStyle; end else jStyle := jStyleConst; //文字変換 case jStyle of jsASCII,jsRoman : begin if (CRLF) and (byte(s[i+skip]) = $0A) then begin //改行コード Result[p] := AnsiChar($0D); Inc(p); end; Result[p] := s[i+skip]; Inc(p); end; jsKana : begin Result[p] := AnsiChar(byte(s[i+skip]) + $80); Inc(p) end; jsOldKanji, jsNewKanji, jsOpKanji : begin b1:= Byte(s[i+skip]); b2:= Byte(s[i+skip+1]); ConvertISO_2022_JPtoShiftJIS(b1,b2); Result[p]:=AnsiChar(b1); Inc(p); Result[p]:=AnsiChar(b2); Inc(p); inc(skip); end; end; //改行コード変換付きの場合バッファが足りなくなる事があるのでチェックを入れます。 if (CRLF) and (p > Len-10) then begin Len:=Len + 10000; SetLength(Result,Len); end; end else begin Dec(skip); end; end; Result[p]:=#0; SetLength(Result,p); end; procedure TForm1.Button1Click(Sender: TObject); var strList:TStringList; s:AnsiString; time:Cardinal; begin //TStringListを用いて読み込み //改行を認識するため若干遅い strList:= TStringList.Create; strList.LoadFromFile('jis.txt'); time:=GetTickCount; s:=ISO_2022_JPtoShiftJIS(strList.Text,False); Caption:=IntToStr(GetTickCount - time) + 'ms'; //Memo1.Text:=s; //大容量ファイルの場合表示は省略 beep; strList.Free; end; procedure TForm1.Button2Click(Sender: TObject); var mStream:TMemoryStream; s:AnsiString; time:Cardinal; begin //TMemoryStreamを用いて読み込み //TStringListより処理が簡素化しているため高速 mStream:=TMemoryStream.Create; mStream.LoadFromFile('jis.txt'); mStream.Position:=0; SetLength(s,mStream.Size); mStream.Read(s[1],mStream.Size); time:=GetTickCount; s:=ISO_2022_JPtoShiftJIS(s,True); Caption:=IntToStr(GetTickCount - time) + 'ms'; //Memo1.Text:=s; //大容量ファイルの場合表示は省略 beep; mStream.Free; end; end.
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.