Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9356

Node.js で標準入力から同期的に一行読み取る

$
0
0
前座:既存の手法(非同期 or 入力全行) 主に競技プログラミングなどのシーンで標準入力からデータが受け渡されることは多いです。競技でなくとも、同様の形式でコーディングテストが行われることもあります。 こういったときに Node.js だと少し煩雑な手順を取る必要があります。 readline const rl = require("readline").createInterface({ input: process.stdin, output: process.stdout, }); const lines = []; rl.on("line", (line) => { lines.push(line); // ... 多分入力処理 }); rl.on("close", () => { // 入力が閉じたのでデータは受け取った // データを全て受け取った前提の処理がここ }); 何も知らない人から見ると呪文です。 上から順に実行されるのはそうなのですが、rl.on では「イベントに対するコールバックを設定」という処理が行われるだけなので rl.on("line", ...); の直後に処理を書いたとしてもデータが入っているとは限らないのが罠です。 インタラクティブな場面では気持ちがいいかもしれません。 fs.readFileSync const fs = require("fs"); const wholeInput = fs.readFileSync("/dev/stdin", "utf8"); const inputLines = wholeInput.split("\n"); const n = Number(inputLines[0]); // ... こちらは比較的まともです。標準入力からの入力を全て文字列として受け取るものです。 強いて欠点を挙げるとすれば以下のようになるでしょう。 インタラクティブな場面には向かない 行を取るには split してインデックスを指定する必要がある 作ってみた 正直上の二つがあれば特に困らないのですが、例えば ruby や python などで簡単に利用できる gets や input() などのような関数が Node.js にもあればなあ、と思い作ってみました。 使う ローカルにインストールして利用する場合は npm で直接 github 上のリポジトリを指定してください。 $ npm install --save git+https://github.com/cwd-k2/node-gets.git 以下のような書き心地になります。 const gets = require("node-gets").createGets(); const n = Number(gets().trim()); const a = gets().trim().split(" ").map(Number); // ... 問題点 テストがない ベンチマークがない 実装上の問題 一行読むたびに内部のバッファでコピーが発生している(リングバッファにすべきなど色々あると思います) \n 以外の文字での分割に対応していない 最後に 他に問題点があったり、直してやったぞということがあれば issue や PR をお願いします。

Viewing all articles
Browse latest Browse all 9356

Trending Articles