標準入出力
基本
ファイル操作のついでに標準入出力について説明しておきます。
実は、標準入力、標準出力、標準エラー出力の3点セットになっています。
標準入力 | キーボードからの入力 |
標準出力 | 画面出力 |
標準エラー出力 | 画面出力 |
'ファイル名は[std.abp]とします。
#console
#include<vcrt71.sbp>
Dim c As Long
While(c <> EOF)
c = getchar()
putchar(c)
Wend
exit(0)
これは標準入力から1文字読み込んで標準出力に出力するだけです。
[Ctrl] + [C]で終了します。
D:\ABtest>std
abc
abc
^C
D:\ABtest>
ここで、標準入力をファイルに変えます。
D:\ABtest>std < std.abp
'ファイル名は[std.abp]とします。
#console
#include<vcrt71.sbp>
Dim c As Long
While(c <> EOF)
c = getchar()
putchar(c)
Wend
exit(0)
D:\ABtest>
標準出力を変えるとどうなるでしょうか。
D:\ABtest>std > out.txt
10 SCERRN 0:WIDTH 40:CLS 3
20 INPUT A
30 IF A<1 THEN PRINT "シゼンスウヲニュウリョクシテクダサイ":GOTO 20
40 B=INT(RND()*10)+1
50 IF A=B THEN PRINT "ダイキチ!"
60 END
^C
D:\ABtest>
出力が画面からファイルに変わったため、文字のエコーはありません。変わりにファイルout.txtが作られます。
stdin stdout
標準入出力で遊んだところで、いよいよ本題です。
fprintf関数とprintf関数、実は同じです。
stdoutは出力が画面の特殊なファイルポインタです。
stdinというのもあります。常にキーボード入力のファイルポインタです。
stdin/stdoutを使った例です。
#include<vcrt71.sbp>
#console
Dim c As Long
fprintf(stdout , "[Ctrl] + [C] で終了します。")
while(c <> EOF)
c = fgetc(stdin)
fputc(c, stdout)
Wend
fprintf(stdout , "終わり")
exit(0)
このプログラムは最初のプログラムと同じです。(こちらは余分なメッセージを表示させていますが)
標準入出力を明示的に使っているだけです。
標準入出力の使い道
stdin/stdoutの使い道について触れておきます。
それはバッファオーバーラン対策です。
バッファオーバーランとは、バッファ(配列)のサイズ以上にデータが書きこまれることです。
有名な例としてgets関数があります。
#include<vcrt71.sbp>
#console
Dim buf[10] As Byte
gets(buf)
puts(buf)
exit(0)
このプログラムはgetsを使って文字列を入力します。
ただ、bufは10バイトしか確保していません。
getsはエンターキーが押されるまで待機するため、バッファがあふれてしまい、
アクセス違反のエラーでプログラムが落ちる可能性があります。
そこで、fgets関数を使うことでこの問題を解決できます。
#include<vcrt71.sbp>
#console
Dim buf[10] As Byte
fgets(buf , 10+1 , stdin)
puts(buf)
exit(0)
これでbufに10文字読み込んだ時点で、入力をやめ、次の処理に進むことができます。
実行結果です。↓
1234567890abcdefghi
1234567890
stderr
おまけ。stderrというのもあります。
エラー出力用で、普通のリダイレクトは通用しません。
2>のようにします。
2はファイル記述子です。(1だとstdout、0はstdin)
まあファイルの番号です。
N88BASICの[OPEN "hoge" As #1]と同じようなものです。ただCは0,1,2がシステム専用なだけです。