【Node.js个人学习笔记】【Readline篇】1.readline单行输入与多行输入的简单运用

时间:2024-04-03 12:07:44

关于readline

        readline是Node.js中实现控制台输入输出的模块,而通过模块的接口我们可以实现逐行读取输入流,类似Java中的Scanner

使用readline

        在使用readline之前我们需要对readline中Interface类的 close事件line事件 有个简单的认识。

    一、‘line’ 事件:

            当输入流接收到行结束符 ("\n","\r",或者"\r\n") 时则触发line事件,一般情况下会在用户按下【Enter】回车键后触发 (在Mac中则是【Return】键) ,当该事件被调用时,监听器函数则会返还在控制台输入的这一行字符串。

举例:

//导入readline模块
var readline = require('readline');

//创建readline.Interface实例
var readlineTest = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

//line事件
readlineTest.on('line', function(line){
	console.log("您输入了:"+line);
    r1.close();
});

//close事件
readlineTest.on('close', function() {
    process.exit(0);
});

当在控制台输入 ‘Hello’ ,则控制台输出 您输入了:Hello
注意:此时若没有使用close事件,则程序不会结束。

    二、‘close’ 事件:

            以下是Node.js官方API文档对于close事件的介绍,一句话概括的话就是:

                    当readline.Interface实例执行close事件后,readline.Interface实例就会结束。
【Node.js个人学习笔记】【Readline篇】1.readline单行输入与多行输入的简单运用
例如,创建一个readline.Interface实例,并调用 ‘line’ 事件,若没有调用close事件,则程序调用的’line’事件不会结束,而当close事件被调用时,readline.Interface实例才会结束。

readline实现单行输入与输出

具体代码模块如下:

//导入readline模块
var readline = require('readline');

//创建readline.Interface实例
var readlineTest = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

//line事件
readlineTest.on('line', function(temp){
	//代码块
    readlineTest.close();//使readline.Interface实例结束
});

//close事件
readlineTest.on('close', function() {
    process.exit(0);
});

首先我们需要导入readline模块,接着创建一个readline.Interface实例,随后调用line事件等待输入信息,接收到输入信息temp后运行代码块,再接着执行close事件结束readline.Interface实例。

实例1 实现a+b=c

//导入readline模块
var readline = require('readline');

//创建readline.Interface实例
var readlineTest = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

//创建一个空数组来存储控制台输入的内容
var numberArray=[];
//初始化结果值
var result=0;

//line事件
readlineTest.on('line', function(line){
    //将控制台输入内容去前后空格和换行符,再按空格分割,形成一个新数组,并且赋给数组numberArray
	numberArray=line.trim().split(" ");
    //通过遍历将数组元素中可以转换为数值的元素转换为number类型
    for(var i in numberArray){
        numberArray[i]=Number(numberArray[i]);
    }
    //将数组元素叠加后的值赋值给result
	result=numberArray.reduce(function(total,next){
        return total+next;
    },0);
    //打印输出
    console.log(numberArray[0]+" + "+numberArray[1]+" = "+result);
    readlineTest.close();//使readline.Interface实例结束
});

//close事件
readlineTest.on('close', function() {
    process.exit(0);
});

控制台输入格式:
Example: 10 20
数字之间用一个空格隔开
运行截图:
【Node.js个人学习笔记】【Readline篇】1.readline单行输入与多行输入的简单运用
此处line事件亦可替换为question事件,关于question事件由于笔者未深入了解,若有需要请跳转至node.js官方API文档查看详细说明。

node.js官方API文档-question事件: http://nodejs.cn/api/readline.html#readline_rl_question_query_callback

readline实现多行输入操作

(1)参数写死的多行输入
具体模板如下


//  引入readline模块
var readline = require('readline');

//  创建一个readline接口实例
var readlineTest = readline.createInterface({
    
    input: process.stdin,
    output: process.stdout
    
});

var lineCounts=4;//输入的行数,参数写死
var tempArray=[];//创建数组来存储每一行的数据
var tempArrayIndex=0;//初始化数组的索引

readlineTest.on('line', function(line){
    
    //将每一行的内容添加至数组tempArray
    tempArray[tempArrayIndex]=line;
    tempArrayIndex++;
    
    //当已输入的行数达到最大输入的行数时,结束readline.Interface实例
    if(tempArray.length==lineCounts){
        console.log(tempArray);//用于调试,可删去
        readlineTest.close();
    }
    
});

//当readlineTest执行'close'命令时,输入流关闭,程序结束。
readlineTest.on('close', function() {
    
    process.exit(0);
    
});

首先,代码中的lineCounts表示写死的行数,例如,若想输入3行,则将lineCounts的值设为3。已知line事件返回的line为在控制台输入的内容,并且是以String形式返还。我们将line写入空数组,当需要处理控制台输入的元素时,则调用数组中相应的元素。当数组的长度等于lineCounts,那么说明输入的行数已经到达最大,此时则结束readline.Interface实例。

实例:多行输入 a+b=c


//  引入readline模块
var readline = require('readline');

//  创建一个readline接口实例
var readlineTest = readline.createInterface({
    
    input: process.stdin,
    output: process.stdout
    
});

var numberArray=[];//创建数值数组来存储每一行的数据
var numberArrayIndex=0;//初始化数值数组的索引
var lineCounts=4;//输入的行数,参数写死
var result=0;//初始化结果值
var str="";//整合式子
readlineTest.on('line', function(line){
    
    //将每一行的内容转换为数字后添加至数值数组numberArray
    numberArray[numberArrayIndex]=Number(line);
    numberArrayIndex++;
    
    //将数组每个元素叠加后赋值给result
    result=numberArray.reduce(function(total,nextTemp){
        return total+nextTemp;
    },0);
    
    //当已输入的行数达到最大输入的行数时,结束readline.Interface实例
    if(numberArray.length==lineCounts){
        //组合式子
        for(var i in numberArray){
            if(i==numberArray.length-1){
                str+=numberArray[i]+"="+result;
            }else{
                str+=numberArray[i]+"+";
            }
        }
        //打印结果式子
        console.log(str);
        readlineTest.close();
    }
    
});

//当readlineTest执行'close'命令时,输入流关闭,程序结束。
readlineTest.on('close', function() {
    
    process.exit(0);
    
});

运行效果图:
【Node.js个人学习笔记】【Readline篇】1.readline单行输入与多行输入的简单运用
标注:这里我将lineCounts设定为4

缺点:参数写死

参数写死对于用代码的人是非常不方便的,因此不推荐这种做法,这里笔者只是以案例介绍这种多行输入的方法,每次用代码都得修改代码中的变量是一件非常没有效率的事情。

(2)控制台自定义行数
想法:将控制台输入的第一行的值作为接下来控制台还可输入的行数,将接下来控制台输入的内容写入新的数组,方便代码块处理。

具体模板代码:


//  引入readline模块
var readline = require('readline');

//  创建一个readline接口实例
var readlineTest = readline.createInterface({
    
    input: process.stdin,
    output: process.stdout
    
});

var linesArray=[];//该数组用来存储输入的内容

var linesArrayIndex=0;//设置存储输入内容数组的索引初始值

var resultArray=[];//该数组用来存储除输入内容第一行外其他行的输入内容

readlineTest.on('line', function(line){
    
    //将存储输入内容的数组linesArray的第一个元素linesArray[0]的值设置为允许输入的行数
    if(linesArrayIndex==0){
        linesArray[linesArrayIndex]=Number(line);
        //打印控制台输入的第一行内容:"允许输入的行数"
        console.log("允许输入的行数: "+linesArray[0]);
    }
    
    //将每一行的内容作为一个单元写入数组linesArray,并且每写入一个元素则数组下标linesArrayIndex自增1
    linesArray[linesArrayIndex]=line;
    linesArrayIndex++;
    
    //调用Array对象的slice()方法返回linesArray数组的子数组(该子数组的内容为: 除linesArray数组第一个元素外的其他元素)
    //将子数组的每个元素依次添加至结果数组resultArray
    for(var i in linesArray.slice(1)){
        resultArray[i]=linesArray.slice(1)[i];
    }
    
    //当输入内容的行数等于linesArray数组的第一个元素(即允许输入的行数)时,则关闭输入流readline
    if(resultArray.length==linesArray[0]){
        //打印输出整合在数组resultArray中的输入内容
        console.log(resultArray);
        readlineTest.close();//关闭输入流
    }
    
});

//当readlineTest执行'close'命令时,输入流关闭,程序结束。
readlineTest.on('close', function() {
    
    process.exit(0);
    
});

模板运行实例:
【Node.js个人学习笔记】【Readline篇】1.readline单行输入与多行输入的简单运用
如图,笔者在控制台输入数值 5,随后控制台允许输入5行内容,待5行内容输入完毕,按下回车后,结果数组打印输出。
流程实现:
首先,将第一行输入内容设定为接下来控制台允许输入的行数,已知linesArray数组用来存储控制台输入的每一行内容,而所需的内容则是除了第一个元素外的其他元素,因此,for in 循环用来为结果数组resultArray依次添加linesArray的子数组中的每个元素,也就是 linesArray.slice(1)后得到的linesArray子数组(注意:Array对象的slice()方法执行后不改变原数组,但linesArray.slice(1)代表的是除去第一个元素后的linesArray数组),最后判断设定行数后输入的行数是否等于linesArray数组第一个元素,若等于则结束readline.Interface实例。

实例:自定义行数多行输入 a+b=c


//  引入readline模块
var readline = require('readline');

//  创建一个readline接口实例
var readlineTest = readline.createInterface({
    
    input: process.stdin,
    output: process.stdout
    
});

var linesArray=[];//该数组用来存储输入的内容

var linesArrayIndex=0;//设置存储输入内容数组的索引初始值

var resultArray=[];//该数组用来存储除输入内容第一行外其他行的输入内容

var result=0;//总值

var str=""//整合式子

readlineTest.on('line', function(line){
    
    //将存储输入内容的数组linesArray的第一个元素linesArray[0]的值设置为允许输入的行数
    if(linesArrayIndex==0){
        linesArray[linesArrayIndex]=Number(line);
        //打印控制台输入的第一行内容:"允许输入的行数"
        console.log("允许输入的行数: "+linesArray[0]);
    }
    
    //将每一行的内容作为一个单元写入数组linesArray,并且每写入一个元素则数组下标linesArrayIndex自增1
    linesArray[linesArrayIndex]=Number(line);
    linesArrayIndex++;
    
    //调用Array对象的slice()方法返回linesArray数组的子数组(该子数组的内容为: 除linesArray数组第一个元素外的其他元素)
    //将子数组的每个元素依次添加至结果数组resultArray
    for(var i in linesArray.slice(1)){
        resultArray[i]=linesArray.slice(1)[i];
    }
    
    //将resultArray数组的元素叠加后的值赋值给result
    result=resultArray.reduce(function(total,nextTemp){
        return total+nextTemp;
    },0);
    
    //当输入内容的行数减一后等于linesArray数组的第一个元素(即允许输入的行数)时,则关闭输入流readline
    if(resultArray.length==linesArray[0]){
        //整合式子
        for(var i in resultArray){
            if(i==resultArray.length-1){
                str+=resultArray[i]+"="+result;
            }else{
                str+=resultArray[i]+"+";
            }
        }
        //打印输出整合后的式子
        console.log(str);
        readlineTest.close();//关闭输入流
    }
    
});

//当readlineTest执行'close'命令时,输入流关闭,程序结束。
readlineTest.on('close', function() {
    
    process.exit(0);
    
});

运行截图
【Node.js个人学习笔记】【Readline篇】1.readline单行输入与多行输入的简单运用

缺点:该方法不够灵活。

虽然能够自定义设置之后输入的行数,但是代码还是不够简洁明了,而且这两种多行输入的方法笔者认为有点傻瓜式,笔者也尝试了多个readline.Interface实例,也就是由一个readline.Interface实例来唤醒其他readline.Interface实例,由于能力有限,代码没写出来。
顺带一提,笔者的代码是基于 node.js10.11 版的,旧版本没有尝试是否能够运行,这里笔者希望如果读者有更好的代码不妨与笔者分享,笔者想更深入学习,亦或读者有何建议也欢迎私信笔者或者留言在评论区,并且本文也参考了一些资料与API文档,相关链接将在文末补全,以上案例和模板都将在blog发布后上传至Github和百度云盘,综上。

源代码:

1.Github

https://github.com/Viviendennis/Aika/tree/master/Readline单多行输入简单运用

由于我是第一次Github,并不知道如何分享文件链接,就直接复制链接过来了,后续更改吧。

2.百度云盘

https://pan.baidu.com/s/1zr_vDmRWrmAGMAQ_sSVIZw
mm:khph

参考的资料与API文档

(顺序无关轻重)
1.博主zgljl2012
【Node.js基础篇】(九)使用readline模块实现Node.js的输入输出

https://blog.csdn.net/zgljl2012/article/details/48321171

2.博主KatherineLYP
JavaScript - nodejs在线编程题获取控制台输入

https://blog.csdn.net/KatherineLYP/article/details/77640519

3.Node.js官方API文档中关于readline的介绍:

http://nodejs.cn/api/readline.html

4.W3school网站的JavaScript教程

http://www.w3school.com.cn/b.asp

5.MDN上的JavaScript技术文档:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript