Help us understand the problem. What is going on with this article?

fgetsとかSTDINとか標準入力がわからなくてPaizaスキルチェックを始められない方へ

はじめに

Paizaでは問題や解答のヒントをSNSなどに記載することは禁じられています。本記事は、その問題を解く以前の大前提を整理したもので、一般に公開されている「値取得・出力サンプルコード」を中心に解説したものですので、禁止事項に当たらないと認識していますが、万が一問題を指摘されたら非公開とします。

さて、プログラミングを学び始めて、もっと実力を磨くために、問題集みたいなのないかなーと探してPaizaに辿り着いたまではいいものの、「標準入力?fgets?STDIN?何それ?」「標準入力の値の取得方法は下記ページのサンプルコードを参照ください。って言うから値取得・出力サンプルコード見たけど、意味不。」と、当初はDランクの問題ですら、60分以内に解けなかった僕が通ります。

私はPHPを学習しているので、PHP前提でこの記事を作成します。

上級者の方、ツッコミや補足情報あれば、ぜひお願いします。

標準入力

標準入力とは、ここでは、Paizaスキルチェックにおいて、Paiza側から渡されるデータのことです。現時点では、あなたのプログラムの整合性を確認するために、10パターンのデータを用意して、あなたが提出したプログラムをチェックします。そのデータはこの標準入力としてあなたのプログラムに読み込む準備をしておかなくてはなりません。

そこで必要なのが、fgets関数とSTDINというオブジェクト(モノ)です。

fgetsとは

fgetsは関数でPHP公式では、下記のように定義されています。

fgets — ファイルポインタから 1 行取得する

STDINとは

STDINは変数みたいなものです。

まずは1行めをきちんと取り出す

仮に、下記のようなデータが与えられたとします。最終行には改行があります。

1
2
3

この値を取得していくには、下記コードでできます。Paizaでも一番最初に既に用意されているコードですよね。当然ながら$input_lineは別に$iにしても同じです。

$input_line = fgets(STDIN);

出力結果↓

1

わかりづらいですが、1の後に改行が入っています。
これはよろしくないので、trim関数を使ってトリミングしてあげます。

trim — 文字列の先頭および末尾にあるホワイトスペースを取り除く

$input_line = trim(fgets(STDIN));

↑こうすると改行やスペースのない1が取り出せます。

複数行にまたがるデータを取り出す

1行めを取り出すのは簡単でしたが、では2行め以降はどのように取り出したらいいのでしょうか。
fgets関数は「ファイルポインタから 1 行取得する」ので、処理を繰り返すと2行目以降も取り出すことができます。

$a = trim(fgets(STDIN));
$b = trim(fgets(STDIN));
$c = trim(fgets(STDIN));
$d = trim(fgets(STDIN));

echo = $a; //1
echo = $b; //2
echo = $c; //3
echo = $d; //データなし

↑このように2回目のfgetsは2行めを取ってきます。

また、Paizaでは複数行にわたるデータの最初の行はデータ数を渡してきて、2行目からが実際に処理するデータであることが多いです。下記↓のような例です。(しつこいですが、最終行には改行が入ってます。)

3
1
2
3

↑データ自体は先ほどのデータと同じですが、1行めにデータ数の情報(データ3行あるよ〜)が挿入されています。この1行めの数字は、forやwhileの繰り返し構文の条件設定に使います。

$input_line = trim(fgets(STDIN)); //$input_lineには3が代入される

for($i=0; $i < $input_line; $i++) { //←繰り返しの条件設定に使う
 //処理したい内容をここに
}

↑こうすれば0, 1, 2と3回for内の処理が繰り返されることになります。

また、そこで当然ながらデータを使うことになると思いますので、fgets(STDIN)をfor文の中に書いていきます↓。

$input_line = trim(fgets(STDIN)); //$input_lineには3が代入される

for($i=0; $i < $input_line; $i++) {
 $a = trim(fgets(STDIN)); //もう上で一行目の3は使われているので、1から一行ずつ代入されていく
}

↑こうして、一行目のデータをデータ数として使用し、二行目以降を実際のデータとして取り出して料理していくわけですね。

ちなみにこちら↓がPaizaの値取得・出力サンプルコード、PHPバージョンです。引用します。こうして見ると最初の3行はわかりやすくなったのではないでしょうか??4行目からは取得したデータを問題に合わせてコーディングしているだけです。

2
2 5
3 4
$input_line = trim(fgets(STDIN));
for ($i = 0; $i < $input_line; $i++) {
    $s = trim(fgets(STDIN));
    $s = str_replace(array("\r\n","\r","\n"), '', $s);
    $s = explode(" ", $s);
    echo "hello = ".$s[0]." , world = ".$s[1]."\n";
}

最後に

超初歩的な内容ですが、自分が過去に躓いたポイントを頭の中が整理できました。誰かのお役に立てると幸いです。ご指摘もどうぞよろしくお願いします。

kakudaisuke
フランス語を話すなどするプログラミング初心者です。
https://note.com/kakudaisuke
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした