標準入出力

基本

ファイル操作のついでに標準入出力について説明しておきます。
実は、標準入力、標準出力、標準エラー出力の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関数、実は同じです。
printf("format" , arg) = fprintf(stdout , "format" , arg)
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>のようにします。
2はファイル記述子です。(1だとstdout、0はstdin)
まあファイルの番号です。
N88BASICの[OPEN "hoge" As #1]と同じようなものです。ただCは0,1,2がシステム専用なだけです。