テキストにバッファを入れる部分を作りましょう。
//バイトを抜き出す
while Length(str)>0 do begin
byteStr:=Copy(str,1,2);
Delete(str,1,2);
//テキストをバッファに入れる
byteStr:='0x'+byteStr;
try
buf:=StrToInt(byteStr);
except
on EConvertError do begin
showmessage('(´・ω・`)変なの入ってるぽ・・・');
FS.Free;
Exit;
end;
end;
//ファイルにバッファを書き込む
end;
さぁさぁ 一気に増えました。増えた部分をピックアップ
//テキストをバッファに入れる
byteStr:='0x'+byteStr;
try
buf:=StrToInt(byteStr);
except
on EConvertError do begin
showmessage('(´・ω・`)変なの入ってるぽ・・・');
FS.Free;
Exit;
end;
end;
一行目は、さっき切り出した2文字に 0x をつけてます。
a:='0x'+a;
で、aの前に0xが入るのは、まぁ説明しなくてもわかると思います。
a:=a+'尻尾'; なら、aの後ろに入るわけで
おにゃのこ:='猫耳'+おにゃのこ+'尻尾';
ってやれば完璧 ハァハァ
世の中的? に、16進数で書いた数字は、頭に、0x(ゼロエックス
をつけるらしくて、
StrToIntという関数も、0xが付いてると16進数として認識します。
まぁそれは今せつめいしまっすよ
try - except - end; 構文 が出てきました。
自分としては、構文の中で一番難しい奴です。
try
処理
except
例外発生時処理
end;
というように使います。
try-except-end;構文に入ると、
まずは、try - except に書いてある処理が普通に実行されます。
普通にしていればそのあと end の下に行きます。
ところが、もし、try-exceptでエラーが発生すると、
残りの処理は無視して except-end; に行きます。
except-end; では、エラーを扱うオブジェクト、
「例外オブジェクト」 とかいう怪しい奴に基づいて分岐できます。
その時は、
on 例外オブジェクトの型 do begin
その例外が発生した時の処理
end;
という風に分岐します。
今回のソースを追ってみましょう。
try
buf:=StrToInt(byteStr);
except
on EConvertError do begin
showmessage('(´・ω・`)変なの入ってるぽ・・・');
FS.Free;
Exit;
end;
end;
まず、try-exceptが実行されるわけです。
buf:=StrToInt(byteStr);
ですね。
StrToIntは、与えられた「数字の文字列」を数値 にして返します。
数字の文字列 っていうのは、
「0,1,2,3,4,5,6,7,8,9」の文字でできた文字列 ってことです。
StrToIntは、文字列の頭が、
「0x」だと、16進数の文字列として読み取り、
「0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,A,B,C,D,E,F」
に対応する・・・
ここまで書いて気付いた。IntToStrを使えばいいのに、
さっきまでHexToBinを使う気だったので、混乱してましたが、
IntToStrの場合、小文字に変換する処理が必要ないですwww
後で直します。
さて、
buf:=StrToInt(byteStr);
これで0xをつけた16進数テキストの入っているbyteStrを変換して、
byte型のbufに入れるわけです。
で、try-exceptを使ってるんだから、エラー、いや 例外オブジェクトが
発生する可能性があるわけです。
なぜか。
StrToIntは、解析できない文字が出てくると、
EConvertError 型の例外を発生するのです。
もし発生した場合、
bufに代入される前に右辺が計算されているので、
StrToIntから即座にexcept-endに飛びます。
あと絶体絶命危機一髪のところで、「buf:=」はシカトされます。
でわ、except-endを見て見ましょう。
on EConvertError do begin
showmessage('(´・ω・`)変なの入ってるぽ・・・');
FS.Free;
Exit;
end;
ですね。
on 例外オブジェクトの型 do begin
その例外が発生した時の処理
end;
ですから、
この場合、
EConvertErrorが発生していたら、begin-endを通ります。
では、begin-endを注目
showmessage('(´・ω・`)変なの入ってるぽ・・・');
FS.Free;
Exit;
showmessageは文字列を引数にダイアログを出す命令でしたね。
手軽なので自分は良く使います。
一個飛ばして、一番最後にExit;
困ったから手続きを強制終了しちゃうわけですね。
このExitの前にFS.free;があるのはカナリ重要です。
もし、これを書かないでExit;しちゃった場合、
「ファイルを開きっぱなしのまま」になります。
しかも、次、この手続きに来たときは、
FS:=TFileStream.Create(略);
でFSの枠に、新しいTFileStreamのインスタンスがはめられちゃうわけですから、
古いファイルストリームは永遠に制御できなくなる
という恐怖の自体が発生します。
アプリケーションが終了するまでメモリを食い続けるファイルストリーム・・・
ざわ・・・ざわざわ・・・・・・ざわ・・・・・
というわけで、手続きを強制終了したりするようなコードを書くときは、
そこまでに生成したインスタンスを解放するのは
ビルゲイツとのお約束ですよ
まぁまとめると、
「バイナリ1バイト分を表すテキストを、
実際に数値に変換し、bufに代入するが、
もし変換できなかったら、
「(´・ω・`)ダイアログ」を出した後、
使うつもりだったファイルストリームを解放し、
強制終了する」
っていう分です。 うわ 複雑!むず!
ま、そんな感じ。
さて、小文字に変換するコードが要らなかったので、削除しましょう。
//大文字を小文字にする
str:=LowerCase(str);
を
に。
ここでいったん確認してみますか。
procedure SaveBinText(SaveTo:String);
var
line:Integer;
buf:Byte;
str:String;
hsp:Integer;
byteStr:String;
begin
FS:=TFileStream.Create(SaveTo,fmCreate);
//ここに処理
for line:=0 to Form1.Memo1.Lines.Count-1 do begin
//一行あたりの処理
str:=Form1.Memo1.Lines[line];
//半角スペースを抜く
while True do begin
hsp:=pos(' ',str);
if hsp=0 then break;
Delete(str,hsp,1);
end;
//バイトを抜き出す
while Length(str)>0 do begin
byteStr:=Copy(str,1,2);
Delete(str,1,2);
//テキストをバッファに入れる
byteStr:='0x'+byteStr;
try
buf:=StrToInt(byteStr);
except
on EConvertError do begin
showmessage('(´・ω・`)変なの入ってるぽ・・・');
FS.Free;
Exit;
end;
end;
//ファイルにバッファを書き込む
end;
end;
FS.Free;
end;
もうこんなになってます。
ちょっとずつ作ると、長いプログラムでもなんてことないですよね。
まぁ、あとちょこっとですが 先走ってみた。
またあとで。
コンテンツ
最新の12件
2023-06-12
2021-02-15
2013-06-19
2012-07-14
2012-02-04
2012-01-06
2011-03-31
2010-08-26
2010-03-15
2009-10-21
2009-02-12
2008-11-18
メニュー編集
- counter: 1062
- today: 1
- yesterday: 0
- online: 2