How to read standard input in Node JS to wirte a program for adding two numbers from user input

Viewed 397

I wanted to solve the problem in node js:

Write a program for adding two integers. At the input, two natural numbers A and B less than 200 are given on separate lines. The output should contain the value of their sum, A + B. (https://pl.spoj.com/problems/PTEST/)

My first attempt:

const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
 
rl.question("A ? ", function(A) {
  rl.question("B ?\n", function(B) {
    console.log(parseInt(A) + parseInt(B));
    rl.close();
  });
});

The second attempt:

const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
  
readline.question('', A, B => {
  console.log(parseInt(A)+parseInt(B));
  readline.close();
});

but both don't work (https://pl.spoj.com/submit/PTEST/)

1 Answers

Reading input through read-line seemed complicated to me so I wrote a small scanner object to accomplish the task.

The scanner has three properties str , num , and int that returns a promise of string, number and integer respectively. All of them returns a promise so you've to await them to get the input value.

So using my scanner object your program would be like the following in index.js. Note: see the Scanner.js module below.

index.js

const scanner = require("./Scanner");

// We're not using console.log because it prints
// an extra new line character.
function print(data) {
  process.stdout.write(data);
}

async function main() {
  // All your code goes here

  print("Enter number A: ");
  const a = await scanner.int();
  print("Enter number B: ");
  const b = await scanner.int();

  print(`A + B = ${a + b}`);

  // Your code ends here

  process.exit(1); 
  // as we're still listening to process.stdin in the Scanner module
  // the program won't quit automatically so we've to terminate the
  // program manually.
}

main();

Scanner.js

const returnPromise = (self) => new Promise((res) => (self.resolve = res));

const scanner = {
  numTypes: ["int", "num"],
  type: "",
  resolve: null,

  handleInput(data) {
    if (!this.resolve) return;

    if (this.numTypes.includes(this.type)) {
      data = Number(data);
      if (Number.isNaN(data)) throw new Error(`Input must be a number.`);

      if (this.type === "int" && !Number.isSafeInteger(data))
        throw new Error(`Input must be a safe integer.`);
    } else data = data.slice(1, -1); // Trim the trailing new line char

    this.resolve(data);
    this.resolve = null;
  },

  num() {
    this.type = "num";
    return returnPromise(this);
  },

  int() {
    this.type = "int";
    return returnPromise(this);
  },

  str() {
    return returnPromise(this);
  },
};

scanner.handleInput = scanner.handleInput.bind(scanner);

process.stdin.setEncoding("ascii");
process.stdin.on("data", scanner.handleInput);

module.exports = scanner;
Related