Eduardo Pascual Aseff
Eduardo Pascual Aseff

Reputation: 1166

How to process standard input NodeJS, in the console?

I want to write NodeJS code for solving problems like ICPC. The following is an example using a template of www.hackerrank.com for submitting in JavaScript:

process.stdin.resume();
process.stdin.setEncoding('ascii');

var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;
process.stdin.on('data', function (data) {
    input_stdin += data;
});
process.stdin.on('end', function () {
    input_stdin_array = input_stdin.split("\n");
    main();    
});
function readLine() {
    return input_stdin_array[input_currentline++];
}
/////////////// ignore above this line ////////////////////
function main() {
    var s = readLine();
    s = s.split(",");
    s = s.join(" ");
    process.stdout.write(s);
}

I want to code offline, so I need to run the programs in my Windows console. For runnig the srcript using C:users\user>node path\file.js I added at the end of the code the line

main();

and the scripts runs, but it doesn't process the standard input. It gives me and error in "s=s.split()", the error is the following "TypeError: Cannot read property 'split' of undefined". If anyone know how to do node process the standard input please help me.

Upvotes: 2

Views: 6270

Answers (3)

kgangadhar
kgangadhar

Reputation: 5088

You can wait for SIGINT, The SIGINT event is emitted whenever the input stream receives a CTRL+C input, known typically as SIGINT. If there are no SIGINT event listeners registered when the input stream receives a SIGINT, the pause event will be emitted.

When SIGINT is received, your main() function will be called and after returning, The process.exit() will close the process.

So instead of waiting for end event

process.stdin.on('end', function(){
    input_stdin_array = input_stdin.split("\n");
    main();
});

You can wait for 'SIGINT' as below:

process.on('SIGINT', function(){
    input_stdin_array = input_stdin.split("\n");
    main();
    process.exit();
});

Upvotes: 5

Avinash
Avinash

Reputation: 2195

  • First to run this code save the file at any location with .js extension.
  • using Command Prompt, go to that folder.
  • run the script using node js

    node file.js

  • then start typing your input on the console.

  • once done hit Cntrl+C and the code written in the SIGINT process are executed.

  • have made the following changes in the code

    process.stdin.resume();
    process.stdin.setEncoding('ascii');
    
    var input_stdin = "";
    var input_stdin_array = "";
    var input_currentline = 0;
    
    process.stdin.on('data', function (data) {
       input_stdin += data;
    });
    
    process.stdin.on('end', function () {
      input_stdin_array = input_stdin.split("\n");
      main();    
     });
    
    process.on('SIGINT', function(){
       input_stdin_array = input_stdin.split("\n");
       main();
       process.exit();
    });
    
    function readLine() {
      return input_stdin_array[input_currentline++];
    }
    /////////////// ignore above this line ////////////////////
    function main() {
      var s = readLine();
      s = s.split(",");
      s = s.join(" ");
      process.stdout.write(s);
    }
    

Upvotes: 2

Terry Lennox
Terry Lennox

Reputation: 30685

I'd suggest you modify your code to append to an array with each line rather than creating one long string and then splitting it. e.g.

process.stdin.resume();
process.stdin.setEncoding('ascii');

var input_stdin_array = [];
var input_currentline = 0;

process.stdin.on('data', function (data) {
    input_stdin_array.push(data);
});

process.stdin.on('end', function () {
    main();    
});

function readLine() {
    if (input_currentline >= input_stdin_array.length) {
        return "";
    }

    return input_stdin_array[input_currentline++];
}

/////////////// ignore above this line ////////////////////
function main() {

    do
    {
        var line = readLine();
        console.log("Line: " + line)
    } while ((line||"") !== "")
}

In addition, as the other answer says, you want to listen to 'SIGINT' rather than 'end'.

I'd also suggest using the Readline module, like so:

var readline = require('readline');
var reader = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: true
});

var lines = [];

reader.on('line', function (line) {
    lines.push(line);
});

reader.on('close', function (line) {
    console.log('All done:');
    console.log('Lines: ', lines);
});

You can trigger 'close' using CTRL-D.

Upvotes: 4

Related Questions