HOME Sather を試そう 書き込む

6. IO


1. はじめに

今回は入出力について説明します。
Sather の IO の機能は意外と豊富で、十分実用的なプログラムを書くことができます。

2. 標準出力, 標準エラー出力, 標準入力

2.1. 標準出力

今まで何度か見てきたように、標準出力は #OUT で作り、'+’に続けて出力したいオブジェクトを書きます。 オブジェクトは文字列への変換方法が定義されているものなら何でも出力できます。
例:
a:INT:=1;
b:INT:=2;
#OUT + a + " + " + b + " = " + (a+b) + "\n";    -- 1 + 2 = 3

2.2. 標準エラー出力

#ERR で作ります。それ以外は標準出力と同じです。標準出力がリダイレクトされても、 モニターに出力されます。

2.3. 標準入力

#IN で作ります。
以下のようなメソッドがあります。
関数 帰り値の型 説明
eof BOOL 入力の終わりなら true を返します。
get_char INT 一文字読み込んで、それを整数として返します。
get_str STR 行末まで読み込みます。改行文字は含めません。

例:ユーザーの入力を 2--5 回繰り返えして出力するプログラム。

01:     -- a simple stdin -> stdout program
02:     
03:     class MAIN is
04:        main(av: ARRAY{STR}) is
05:           i:INT:=0;
06:           s:STR;
07:           loop
08:     	 #OUT + ">";
09:     	 s:=#IN.get_str;
10:     	 if s = "" then break!; end;
11:     	 #OUT + (s+" ").repeat(i+2) + "\n";
12:     	 i := (i+1)%4;
13:           end;
14:        end;
15:     end;  -- end of MAIN
takafumi@linux:~/doc/monthly/06-06/sather$ sacomp inout.sa -o inout
takafumi@linux:~/doc/monthly/06-06/sather$ ./inout
>hello
hello hello 
>how are you?
how are you? how are you? how are you? 
>enjoy!
enjoy! enjoy! enjoy! enjoy! 
>have a nice day!
have a nice day! have a nice day! have a nice day! have a nice day! have a nice day! 
>see you tomorrow.
see you tomorrow. see you tomorrow. 
>
takafumi@linux:~/doc/monthly/06-06/sather$ 

3. ファイル入出力

ファイル入出力に関するメソッドは class FILE に定義されています。 下の表に主なものを挙げておきます。
詳しくは The Online Sather Code Browser をみてください。

表:FILE クラスの主なコンストラクターおよびメソッド
コンストラクター、メソッド 説明
open_for_read(nm:STR):SAME 名前 nm のファイルを読み込み用に開きます。
open_for_write(nm:STR):SAME 名前 nm のファイルを書き込み用に開きます。
open_for_append(nm:STR):SAME 名前 nm のファイルを追加書き込み用に開きます。
temp_file:SAME 書き込み用に一時ファイルを作ります。プログラムの終了後自動的に削除されます。
stdin:SAME 標準入力としてファイルを開きます。
stdout:SAME 標準出力としてファイルを開きます。
stderr:SAME 標準エラー出力としてファイルを開きます。
close ファイルを閉じます。
str:STR ファイルの内容を文字列で返します。
get_str:STR ファイルから1行読み込みます。改行文字も含まれます。
get_char:CHAR ファイルから一文字読み込みます。
plus (+) ファイルにオブジェクトを書き出します。fp + obj のように書くことができます。
flush バッファをファイルに書き出します。
eof:BOOL ファイルの終端なら true を返します。
error:BOOL ファイルを開けないなどのエラーが発生していれば true を返します。

例として、Sather で書いた cp (scp.sa) と cat (scat.sa) を挙げておきます。

scp.sa

01:     -- scp.sa: a simple cp program written in sather
02:     
03:     class MAIN is
04:     
05:        main(av: ARRAY{STR}) is
06:           if (av.size = 3) then
07:     	 f0:FILE:=FILE::open_for_read(av[1]);       -- av[1] を f0 として開く
08:     	 if f0.error then
09:     	    #ERR + "Can not open " + av[1] + "\n";  -- 開けなかったらその旨を表示
10:     	 else
11:     	    f1:FILE:=FILE::open_for_write(av[2]);
12:     	    f1 + f0.str;                            -- f0 の内容を f1 に書き出す。
13:     	    f0.close;
14:     	    f1.close;
15:     	 end;
16:           else
17:     	 #ERR + "Usage: scp [from] [to]\n";
18:           end;
19:        end;
20:     end;  -- end of MAIN
scat.sa
01:     -- scat.sa: a simple cat program written in sather
02:     
03:     class MAIN is
04:     
05:        show_file_contents(f:FILE) 
06:           pre ~f.error
07:        is
08:           loop
09:     	 until!(f.eof);                    -- check if it reaches the end of file
10:     	 #OUT + f.get_str;                 -- getting one line
11:           end;
12:        end;
13:     
14:        main(av: ARRAY{STR}) is
15:           if (av.size = 1) then
16:     	 show_file_contents(FILE::stdin);
17:           else
18:     	 i:INT;
19:     	 f:FILE;
20:     	 loop
21:     	    i:=1.upto!(av.size-1);
22:     	    if av[i] ="-" then
23:     	       f:=FILE::stdin;
24:     	    else
25:     	       f:=FILE::open_for_read(av[i]);
26:     	    end;
27:     	    if f.error then
28:     	       #ERR + "Can not open " + av[i] + "\n";
29:     	       break!;
30:     	    else
31:     	       show_file_contents(f);
32:     	       f.close;
33:     	    end;
34:     	 end;
35:           end;
36:        end;
37:     end;  -- end of MAIN

4. フォーマット

いろいろな方法がありますが、FMT クラスを使うのが簡単でしょう。 このクラスは、書式文字列とオブジェクト(複数指定可)を引数に取り、フォーマットされた文字列を返します。 書式文字列としては、Sather 独自の指定方法と C 言語と同じものが使えます。また、両者を混在させることができます。 C の書式が使えるのは STR, INT, FLT だけなので、そのほかのデータ型には sather 方式を使う必要があります。

Sather 形式について詳しくは Formatting output with Sather をみてください。

例:

01:     -- fmt.sa: a simple cp program written in sather
02:     
03:     class MAIN is
04:     
05:        main(av: ARRAY{STR}) is
06:           #OUT + #FMT("%d %06d %X %06X %x %o %06o\n", 255, 255, 255, 255, 255, 255, 255); -- up to ten items
07:     
08:           -- FMT::format takes ARRAY{$FMT} as the second arguement
09:           -- sather and C format notation can be mixed
10:           #OUT + FMT::format("<>: %02d <> <#.#######e##>\n", |"hello", 1, 2.0, FLTD::pi|);  
11:        end;
12:     end;  -- end of MAIN
takafumi@linux:~/doc/monthly/06-06/sather$ sacomp fmt.sa -o fmt
takafumi@linux:~/doc/monthly/06-06/sather$ ./fmt
255 000255 FF 0000FF ff 377 000377
hello: 01 2.0 3.1415930e00

5. 終わりに

IO に関しては実はいろいろな方法があるのですが、全てを書くとかえって読者が混乱すると思ったので、取捨選択して書きました。
詳しくは The Online Sather Code Browser をみてください。

次回からは Sather のクラスシステムについてさらに詳しく説明します。


HOME Sather を試そう 書き込む