• 検索結果がありません。

ファイル入出力

ドキュメント内 note.dvi (ページ 45-49)

ファイルへの入出力を行なうには,ファイル型変数と,read,write手続きを利用する.

ファイル変数を宣言すると,その要素の型を持ったバッファ変数が自動的に定義される. それをファイル 変数fに対してf^と表す. バッファ変数は,ファイルに対して既存の要素を読みだしたり,書き出したり することができる窓であると理解する. この窓は,ファイル演算によって自動的に移動する.

5.15.1 ファイル処理の関数と演算子

バッファ変数f^がファイルfの終りを通過すれば,標準の論理関数 eof (f)はtrueを返し,そうでな

ければfalseとなる.

ファイル演算子には標準的には次のものがある.

reset(f,filename) 読み込みを開始するために, バッファ変数を初期化する. すなわち, fの最初の要素 に f^をセットする. fが空でなければeof(f) は falseとなる. f が空であればf^は不定となり, eof(f)はtrueとなる.

rewrite(f,filename) ファイルfの書換えをするには, reset(f) の代わりにこれを用いる. このとき, eof(f)はtrueとなる.

get(f) バッファ変数を次の要素に進める. すなわち,次の要素の値をバッファ変数に代入する. そのよう

な要素がなければ,バッファ変数の値は不定となり, eof(f)はtrueとなる.

put(f) ファイルにバッファ変数の値を付け加える. これは,実行の直前でeof(f)が trueの時に限り定 義される. その結果はeof(f)が trueとなり,バッファ変数の値は不定となる.

実際には,get(f),put(f)の代わりに手続きread,writeを用いる. それぞれは,次と等価である.

read(f,x): x := f^ ; get(f) write(f,x): f^ := x ; put(f)

Example 5.15.1 この例は,integerからなるファイルを作成し, そこからデータを読み出している.

var

f : file of integer ; i, n : integer ;

begin

rewrite(f,’integer_file’) ; for i:=1 to 10 do

write(f,i) ; close(f) ;

reset(f,’integer_file’) ; while (not(eof(f))) do begin

read(f,i) ; writeln(i) ; end ;

close(f) end.

利用したファイルは利用後にその利用が終ったことをOSに対して知らせることが必要になることがおお い. そのために利用するのがclose(f)という手続きで, この手続き自身はSPARCompilerで定義されて るものだが,多くの処理系で対応するものが存在する. また,open手続きというのもあり,reset,rewrite よりも細かいファイルの制御が可能になる.

Pascal は OSとの関係については, その仕様には全く含まれないので, このようなOSに関係する部分

に関しては,処理系定義となることが多い.

Id: P7.tex,v 1.3 2001-03-11 17:32:25+09 naito Exp

5.15.2 テキストファイル

テキストファイルに対しては,writeln, readln,eolnが利用できる.

eoln(f) テキストファイル fが現在の行の終りに達したかどうかを判定する. true ならば,バッファ変数

は行末に位置している.

writeln(f,x) テキストファイルfに対して, xを出力し,現在の行を終了する. すなわち,行末文字を印 字する.

readln(f,x) テキストファイルf に対して, xを読み, 次の行の先頭まで読みとばす. バッファ変数は次

の行の最初の文字となる.

ここで, ファイル変数が省略された場合には,writeln は標準出力に対して,readlnは標準入力に対して 行なわれる. また, SPARCompilerでは標準エラー出力はerroutと書かれる.

5.15.2.1 read,readln 手続きread,readlnは, read(file,v1,v2,v3)

といった書き方ができる. この場合, ファイルから,v1,v2,v3を一度に読むことを指示している.

5.15.2.2 write,writeln 手続きwrite,writelnは, write(file,v1,v2,v3)

といった書き方ができる. この場合, ファイルにv1,v2,v3を書き出すことを指示している.

また,これをテキストファイルに適用する場合には,その引数として, e:A:B

といった型をとれる. ここで,A,Bは書き出す長さを指定する部分であり,そのdefaultの値は処理系定義 である.

eはファイルに書き出す値を表した式であり,その型は,整数型, 実数型, 文字型,論理型, 文字列型でな くてはならない.

5.15.2.2.1 文字型の時 文字型の時, e:A

という型をとり,ファイルに書き出される表現は

(A1)個の空白,

eの文字値 である.

5.15.2.2.2 文字列型の時 文字列型の時, e:A

という型をとり,eのあらわす文字列を,つぎのようにして書く. ここで,Lをその文字列の長さとする.

1. A> Lの時.

Id: P7.tex,v 1.3 2001-03-11 17:32:25+09 naito Exp

(A−L)個の空白.

eを順に並べたもの.

2. A≤Lの時.

eを順にA番めまで並べたもの.

5.15.2.2.3 論理型の時 論理型の時, e:A

という型をとり,eの値を文字列true もしくはfalseを利用して書かれる. その文字列は,Aを利用して 書かれる. この時, 文字列が大文字になるか,小文字になるかは処理系定義である.

5.15.2.2.4 整数型の時 整数型の時, e:A

という型をとり,eの10進表現がファイルに書かれ,Aに関しては,次のようになる.

1. AIntDigit+1の時.

(AIntDigit1)個の空白,

eが負の時,符号-,それ以外の時空白

IntDigit桁のabs(e)の10進表現 2. A<IntDigit+1の時.

eが負の時,符号-,それ以外の時空白

IntDigit桁のabs(e)の10進表現

ここで,IntDigitは,その絶対値を10進表現するために必要な最小の桁数.

5.15.2.2.5 実数型の時 実数型の時には,浮動小数点表現と固定小数点表現がある.

5.15.2.2.5.1 浮動小数点表現 e:A

という型をとり,eの浮動小数点表現がファイルに書かれ,Aに関しては,次のようになる.

符号. e<0かつ,eWritten>0の時-,それ以外の時空白,

eWrittenの10進表現の第1桁めの数字,

文字.,

eWrittenの10進表現の第2桁め以降のDecPlaces個の数字,

処理系定義の指数部表現eまたはE,

ExpValueの符号,ExpValue<0 の-,それ以外の時+,

ExpValueのExpDigit桁の10進表現. (必要なら先頭に文字0が並ぶ).

ここで,ExpDigitは処理系定義の値. eWritten,DecPlace, ExpValueは,次のように定義されている.

整数Xに対して,TenPower(X)を 10のX乗の値(実数).

実数Xに対して,RealSize(X)を,次のような整数Z:TenPower(Z-1)abs(X)<TenPower(z).

実数X, 整数Yに対して,Truncate(X,Y)をXの小数点以下Y桁より下を切捨てた実数の値.

とする. この時,ActWidthを

if A >= ExpDigit + 6 then ActWidth := A else ActWidth := ExpDigit + 6 ;

Id: P7.tex,v 1.3 2001-03-11 17:32:25+09 naito Exp

で定義する. これで,eWritten,DecPlace,ExpValueは, DecPlace := ActWidth - ExpDigit - 5 ;

if e = 0.0 then begin

eWritten := 0.0 ; Expvalue = 0 end

else begin

eWritten := abs(e) ;

ExpValue := RealSize(eWritten) - 1 ;

eWritten := eWritten / TenPower(ExpValue) ;

eWritten := eWritten + 0.5 * TenPower(-DecPlace) ; if eWritten >= 10.0 then

begin

eWritten := eWritten / 10.0 ; ExpValue := ExpValue + 1 ; end ;

eWritten := Truncate(eWritten,DecPlace) ; end.

Example 5.15.2 例えば,10.255という値をwriteln(x:9)で表示すると,1.03e+10となる. ExpDigit

= 2とすると, ActWidth = 9, DecPlace = 2, eWritten = 1.0300, ExpValue = 1 となる. 9 は全部の 出力する文字数を表し,符号(1桁),小数点の記号(1桁),e(1桁),指数部(符号を含む)(3桁)の 桁数を引いた残りの桁9-1-1-1-3 = 3桁の仮数部を出力する. その際に, 仮数部の3 + 1 = 4桁めを四 捨五入している.

5.15.2.2.5.2 固定小数点表現 e:A:B

という型をとり,eの固定小数点表現がファイルに書かれ,Aに関しては,次のようになる.

AMinNumChar なら(AMinNumChar)個の空白,

符号. e<0かつ,eWritten>0の時-,

eWrittenの10進表現の最初のIntDigit個の数字,

文字.,

eWrittenの10進表現のその次のB個の数字.

ここで, ExpDigit は処理系定義の値. eWritten は, 次のように定義されている. TenPower, RealSize, Truncateは前と同じ. これで,eWrittenは,

if e = 0.0 then begin

eWritten := 0.0 end

else begin

eWritten := abs(e) ;

eWritten := eWritten + 0.5 * TenPower(-B) ; eWritten := Truncate(eWritten,B) ;

end.

であり,IntDigitは,

if RealSize(eWritten) < 1 then IntDigit = 1

else

IntDigit = RealSize(eWritten) ; MinNumChar は,

Id: P7.tex,v 1.3 2001-03-11 17:32:25+09 naito Exp

MinNumChar := IntDigit + B + 1 ; if (e < 0.0) and (eWritten > 0) then

MinNumChar := MinNumChar + 1 ;

Example 5.15.3 例えば,10.255という値をwriteln(x:3:1)で表示すると,10.3となる. ここのx:3:1 の最初の3は, 全部の桁数を表し, 後ろの1は小数点以下の桁数を表している. ExpDigit = 2 とすれば, eWritten = 10.3,IntDigit = 2,MinNumChr = 4となる. おおよそ,上から3+1=4桁めを四捨五入して いる. 実際には,writeln(10.25:3:1)は 10.2を出力し,writeln(10.250000000000001:3:1) は10.3 を出力する.

Remark 5.15.1 SPARCompilerでは,writeln手続きの桁指定子に関してはもっと多くの自由度がある.

詳しくはSPARCompilerのマニュアルを参照.

5.15.3 演習問題

Exercise 5.15.1 標準入力から入力されたファイルの行数を印字するプログラムを書け.

Exercise 5.15.2 標準入力から入力されたファイルの行数,単語の数,文字数を印字するプログラムを書け.

Exercise 5.15.3 標準入力から入力された1文字が英字でなければ,そのまま印字し, 大文字の英字なら 小文字に,小文字の英字なら大文字を印字するプログラムを書け. ただし,改行だけが入力された場合には, 終了するようにしなさい. また,入力された文字はASCIIコードで表現されていることに注意せよ.

ドキュメント内 note.dvi (ページ 45-49)