おなじみの汎用入力関数です。「scanfには問題があるので使ってはならない」とよく言われますが、Golfではお構いなしです。
読み込みに成功した場合は読み込んだ変数の数を、失敗した場合は-1を返します。
読み込みに成功した場合は読み込んだ変数の数を、失敗した場合は-1を返します。
次のコードは、空白区切りで書かれた2つの整数を一行ごとに読み込むコードです。
次に、「~」(tilde, overline)ですが、これは「ビット反転演算子」です。その名の通り、「~a」はaの全ビットを反転したものです(アドホックに言うと、-1-aと同じ値)。-1というのは全ビットが立った状態ですから、ビット反転すると0になり、for文の終了条件として使えます。このように、scanfが失敗したときに-1を返すことを利用して、ビット反転と共に用いforの終了条件にすることはきわめてよくあります。
main(a,b){for(;~scanf("%d%d",&a,&b);)...;}ポイントは2つ。まず、入力が空白区切りだからといって、scanfの書式に空白を含める必要はありません。空白を読み込んだ時点で自動的に整数と整数の間の区切りだと勝手に判断してくれます。
次に、「~」(tilde, overline)ですが、これは「ビット反転演算子」です。その名の通り、「~a」はaの全ビットを反転したものです(アドホックに言うと、-1-aと同じ値)。-1というのは全ビットが立った状態ですから、ビット反転すると0になり、for文の終了条件として使えます。このように、scanfが失敗したときに-1を返すことを利用して、ビット反転と共に用いforの終了条件にすることはきわめてよくあります。
main(i){scanf("%d%*d",&i);...} //2つ目の整数を読み捨てる書式を「%*d」などすることで、読んだ値を変数に格納せず、捨てることができます。
char s[99];main(){scanf("%[^,],",s);...} //カンマ区切りで読み込み[]で文字列を括ることで、カッコ内の文字だけを読み込みます。ただしカッコの最初に「^」がある場合、カッコ内の文字以外を読み込みます。
より詳しく知りたい方は、気の利いたscanf -- part 1をご覧ください。
おなじみの一行読み込み関数です。「バッファオーバーランを起こす可能性があるので使ってはならない」とよく言われますが、例によってGolfでは動きさえすれば問題ありません。
読み込みに成功した場合は読み込み先文字列へのポインタを、読み込みに失敗した場合は0を返します。
入力関数の中では単純にバイト数が一番短いのでよく用いられます。一行に整数がひとつ書いてある場合、scanfで読み込むよりgets+atoiの方が短かったりします。
読み込みに成功した場合は読み込み先文字列へのポインタを、読み込みに失敗した場合は0を返します。
入力関数の中では単純にバイト数が一番短いのでよく用いられます。一行に整数がひとつ書いてある場合、scanfで読み込むよりgets+atoiの方が短かったりします。
main(i){for(;gets(&i);)...;} main(i,s){for(;gets(s);)...;}読み込みに失敗すると0が返るので、for文の終了条件にできます。また、渡す値はなにもchar*型である必要はなく、とりあえず値を格納できるアドレスであればなんでもいいです。詳しくは変数.cをご覧ください。
読み込みに成功した場合に格納先アドレスが返るのも重要です。例えば一行目に書いてある整数を読み込むときに、
main(i){i=atoi(gets(&i));}などと書くことができます。
さらに付け加えると、
!gets(s)は読み込みに成功すれば0、失敗すれば1となるので便利です。これを用いて短縮できることもあります。
標準入力から一文字読み込み、読み込んだ文字をintで返す関数です。入力関数の中では、これのみ引数なしで呼び出せます。
入力の終端に達すると-1を返すので、そのままではfor文の終了条件に使えません。このため、よくある「標準入力から一文字ずつ読み込んで何かする」ような場合は後述するread()の方が短くなることが多く、getchar()の出番は思いの外少ないのが現状です。とはいえ、読み込んだ値をそのまま返す唯一の入力関数としてしばしば登場します。
なお、引数無しで呼び出せることを利用し、逆にgetchar()のカッコの中に式を入れることでセミコロンを省略できたりします。これは案外盲点です。もちろん、中の式はgetchar()が呼び出される直前に評価されます。
入力の終端に達すると-1を返すので、そのままではfor文の終了条件に使えません。このため、よくある「標準入力から一文字ずつ読み込んで何かする」ような場合は後述するread()の方が短くなることが多く、getchar()の出番は思いの外少ないのが現状です。とはいえ、読み込んだ値をそのまま返す唯一の入力関数としてしばしば登場します。
なお、引数無しで呼び出せることを利用し、逆にgetchar()のカッコの中に式を入れることでセミコロンを省略できたりします。これは案外盲点です。もちろん、中の式はgetchar()が呼び出される直前に評価されます。
Golf以外ではあまり用いられない低水準関数ですが、Golfでは意外とよく用いられます。標準入力から読み込む場合、第一引数を0にすればOKです。
- 入力に成功すると読み込んだバイト数
- 入力の終端に達すると0
- 入力に失敗すると-1
main(i){for(;read(0,&i,1);)...;}1バイトずつiに読み込み処理する典型的なコードです。
main(i){for(;i=getchar(),~i;);...;}とほとんど同じですが、read()を使った方が短くなるので前者が多用されます。
main(n,s){for(n=read(0,s,99);...;)...;}標準入力から99バイト読み込みますが、入力が99バイト以下なら全部読み込んだ上で読み込んだバイト数をnに代入します。入力全部と入力のバイト数が必要なときに便利です。
なお、read()は他の入力関数を使った後には使えないことに注意が必要です。
main(i,s){gets(s);read(0,s,99);...;}などということはできません。
その他、第一引数にopen()の返り値を渡すことでファイルを読み込むなどの使用法がありますが、割愛します。
コメントをかく