Node.js带用户输入计算器构建及问题排查求助
基础计算器程序问题求助
我已经为此折腾了数小时,仍未解决这款基础计算器的以下问题:
- 终端中用户输入不可见,原因是什么?
- 程序运行不符合预期:
- 当触发calculations()的提示时,最终计算结果不显示,被程序忽略,是否是代码结构问题?
- 按'q'退出程序时,需要按两次才生效,这是为什么?
const readline = require('readline'); const readlineSync = require('readline-sync'); // Variables let operations = ['+', '-', '*', '/', 'q', 'add', 'subtract', 'multiply', 'divide', 'quit']; let index = null; let operator = null; let firstNumber = 0; let secondNumber = 0; // function to expect answers and repeat the process recursively let rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); // Console Dialogue let username = readlineSync.question('Hello! What is your name? \n'); console.log('\nGreetings, ' + username + '!\n' + 'Welcome to the Regular Calculator Project.\n'); // run the program console.log(operationQuestion(), exitProgram()); // function to Exit program function exitProgram(){ console.log('The program is complete. Exiting the program now...'); process.exit(0); } // Function to navigate operations function operationQuestion() { operator = readlineSync.question('Please type an operation to perform. Here are your options:\n' +'\nAddition ('+ operations[0]+')' +'\nSubtraction ('+ operations[1]+')' +'\nMultiplication ('+ operations[2]+')' +'\nDivision ('+ operations[3]+')\n' +'\nQuit the Program ('+ operations[4]+')\n\n' ); // check if the user typed the right operator(s) if (!operations.includes(operator)) { console.log('That is not a valid operation. Please try again.\n'); operationQuestion(); } firstNumber = readlineSync.questionInt('Type the first number: '); secondNumber = readlineSync.questionInt('Type the second number: '); quitProgram = readlineSync.question(`Write 'q' again to confirm exit: `); // check if input is to quit, then user will proceed to exit the program if (readlineSync.question(quitProgram) == 'q') { return exitProgram() } // inner function to navigate basic calculations function calculations() { switch(operator) { case '+': case 'add' : case operations[0]: case operations[5]: console.log('The result of ' + firstNumber+operator+secondNumber+ ' = ' + (firstNumber+secondNumber) + '\n'); break; case '-': case 'subtract': case operations[1]: case operations[6]: console.log('The result of ' + firstNumber+operator+secondNumber+ ' = ' + (firstNumber-secondNumber) + '\n'); break; case '*': case 'multiply': case operations[2]: case operations[7]: console.log('The result of ' + firstNumber+operator+secondNumber+ ' = ' + (firstNumber*secondNumber) + '\n'); break; case '/': case 'divide': case operations[3]: case operations[8]: console.log('The result of ' + firstNumber+operator+secondNumber+ ' = ' + ((firstNumber/secondNumber).toFixed(2)) + '\n'); break; case 'q': case 'quit': case operations[4]: case operations[9]: console.log(quitProgram, exitProgram()); break; default: console.log('Something went wrong: '); break; } } return operationQuestion() } rl.on("close", function() { console.log("\nExiting program now..."); process.exit(0); });
问题解答
1. 终端输入不可见的原因
你同时使用了readline原生库和readline-sync第三方库,且创建了readline的接口实例rl,这会干扰readline-sync的输入渲染逻辑。readline-sync是专为同步终端输入设计的,不需要搭配原生readline使用,移除所有readline相关代码即可解决输入不可见的问题。
2. 计算结果不显示的原因
- 你定义了
calculations()函数但从未调用过,计算逻辑完全没执行。 operationQuestion()函数最后直接递归调用自身,导致程序跳过计算步骤直接进入下一轮操作选择。
需要在获取完操作符和数字后,先执行计算,再递归调用operationQuestion()让程序继续运行。
3. 按'q'退出需要两次的原因
- 当用户选择'q'或'quit'时,程序依然执行了输入两个数字的步骤,属于冗余流程,应该在识别到退出操作时直接进入退出确认,跳过数字输入。
- 代码中
readlineSync.question(quitProgram)会把用户第一次输入的内容作为提示,再次弹出输入框要求用户输入,相当于让用户重复确认两次,这是错误的用法。应该直接判断用户第一次输入的quitProgram是否为'q'。
修正后的完整代码
const readlineSync = require('readline-sync'); // Variables let operations = ['+', '-', '*', '/', 'q', 'add', 'subtract', 'multiply', 'divide', 'quit']; let operator = null; let firstNumber = 0; let secondNumber = 0; // Console Dialogue let username = readlineSync.question('Hello! What is your name? \n'); console.log('\nGreetings, ' + username + '!\n' + 'Welcome to the Regular Calculator Project.\n'); // 启动程序 operationQuestion(); // 退出程序函数 function exitProgram(){ console.log('The program is complete. Exiting the program now...'); process.exit(0); } // 操作选择函数 function operationQuestion() { operator = readlineSync.question('Please type an operation to perform. Here are your options:\n' +'\nAddition ('+ operations[0]+')' +'\nSubtraction ('+ operations[1]+')' +'\nMultiplication ('+ operations[2]+')' +'\nDivision ('+ operations[3]+')\n' +'\nQuit the Program ('+ operations[4]+')\n\n' ); // 验证操作是否合法 if (!operations.includes(operator)) { console.log('That is not a valid operation. Please try again.\n'); operationQuestion(); return; // 递归后终止当前函数执行 } // 判断是否选择退出 if (['q', 'quit', operations[4], operations[9]].includes(operator)) { let confirmQuit = readlineSync.question(`Write 'q' to confirm exit: `); if (confirmQuit.toLowerCase() === 'q') { exitProgram(); } else { operationQuestion(); // 取消退出,回到操作选择 } return; } // 获取计算数字 firstNumber = readlineSync.questionInt('Type the first number: '); secondNumber = readlineSync.questionInt('Type the second number: '); // 执行计算 calculations(); // 递归调用,继续程序 operationQuestion(); } // 计算逻辑函数 function calculations() { switch(operator) { case '+': case 'add' : case operations[0]: case operations[5]: console.log(`The result of ${firstNumber}${operator}${secondNumber} = ${firstNumber + secondNumber}\n`); break; case '-': case 'subtract': case operations[1]: case operations[6]: console.log(`The result of ${firstNumber}${operator}${secondNumber} = ${firstNumber - secondNumber}\n`); break; case '*': case 'multiply': case operations[2]: case operations[7]: console.log(`The result of ${firstNumber}${operator}${secondNumber} = ${firstNumber * secondNumber}\n`); break; case '/': case 'divide': case operations[3]: case operations[8]: // 处理除数为0的情况 if (secondNumber === 0) { console.log('Error: Cannot divide by zero!\n'); return; } console.log(`The result of ${firstNumber}${operator}${secondNumber} = ${(firstNumber / secondNumber).toFixed(2)}\n`); break; default: console.log('Something went wrong!\n'); break; } }
内容的提问来源于stack exchange,提问作者Emily Mendez
相关产品推荐
相关产品推荐

