paizaで使える標準入力【PHP】


なぜ?

paizaの公式の標準入力例

phpサンプル
<?php
$input_lines = trim(fgets(STDIN));
for ( $i = 0; $i < $input_lines; $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";
}
?>

Paizaで使える標準入力の取得

<?php

// 標準入力からの入力値を変数に代入します
$single_line_input = fgets(STDIN);
// 取得した入力値を半角スペースで分解します
$array = explode(" ", $input_line);
// 単一行の入力の場合はこれだけで各入力値が配列の要素として使えます

などなどがありますが…。
「クラスやメソッドを利用した取得方法ってどこにも載ってないなー」
と感じたのでメモ程度に載せておきます。

また
paizaは絶対正しい値を送ってくれるけど…
ユーザーなどから値を受け取るものに対して
バリデーションのない製品」を世に出したら…
プログラマーの皆さんはきっと青ざめますよね?
と感じたので

これからpaizaをやる人の為にも
paizaでは教えてくれない「バリデーション」についても
触れられればと思いまとめました。

とりあえずコード

標準入力1
<?php

// 入力サンプル
// 1 2 3
// 4 5 6
// 7 8 9

$objInput = new UserInput;
$objValidation = new InputValidation;
$inputs = $objInput->multiInputLine()->getValue();

foreach($inputs as $key => $value) {
    if($objValidation->isNumeric($value) === false) {
        echo $value;
    }
}
var_dump($inputs);



// ユーザーからの入力値を受け取ります
class UserInput {
  private $stdin    = null;
  private $separate = ' ';

  // 1行のみ
  public function singleInputLine() {
    $single_line_input = trim(fgets(STDIN));
    // 半角スペース分割
    $this->stdin       = explode($this->separate, $single_line_input);

    return $this;
  }

  // 複数行
  public function multiInputLine() {
    // 複数行の取得
    while($lines = fgets(STDIN)) {
      $tmp[] = trim($lines);
    }
    // 配列を分割する
    foreach($tmp as $key => $value) {
         $this->stdin[$key] = explode($this->separate, $value);
    }
    return $this;
  }

  // 値の取得
  public function getValue() {
    return $this->stdin;
  }
}

// バリデーションチェックを行います
class InputValidation{
  // Null&空白チェック
  public function isNull($str) {
    if($str == null || strcmp($str,"") == 0) {
      return false;
    }
    return true;
  }

  // 半角英数のみチェック
  public function isAlphaNumeric($str) {
    if(!preg_match("/^[a-zA-Z0-9]+$/", $str)) {
      return false;
    }
    return true;
  }

  // 半角数字のみチェック
  public function isNumeric($str) {
    if(!preg_match("/^[0-9]+$/", $str)) {
      return false;
    }
    return true;
  }

  // 半角英字のみチェック
  public function isAlpha($str) {
    if(!preg_match("/^[a-zA-Z]+$/", $str)) {
      return false;
    }
    return true;
  }

  // とりあえず半角かチェック
  public function isSingleByteChar($str) {
    if(strlen($str) != mb_strlen($str, 'UTF-8')) {
      return false;
    }
    return true;
  }
}

使い方

例1(大丈夫なら)
...コード省略...

// 入力サンプル
// 1 2 3
// 4 5 6
// 7 8 9

$objInput = new UserInput;
$objValidation = new InputValidation;
$inputs = $objInput->multiInputLine()->getValue();

foreach($inputs as $record) {
    foreach($record as $value) {
        if($objValidation->isNumeric($value) === false) {
            error_log($value ." : is not numric");
        }
    }
}

出力
-> なにも出ない
例1(エラー例)
...コード省略...

// 入力サンプル
// 1 2 a
// b 5 6
// 7 8 c

$objInput = new UserInput;
$objValidation = new InputValidation;
$inputs = $objInput->multiInputLine()->getValue();

foreach($inputs as $record) {
    foreach($record as $value) {
        if($objValidation->isNumeric($value) === false) {
            error_log($value ." : is not numric");
        }
    }
}

出力
-> a : is not numric
-> b : is not numric
-> c : is not numric

おしまい

これはあくまで一例です。
もっと継承を意識した柔軟性かつ芸術的なコードをかけるようになりたいです。

「paizaで使える俺の(私の)標準入力例はイイぞォ」
という方はコメントください。

これをもっと芸術的にしてくれる方もコメント頂けると嬉しいです。

ありがとうございました