You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js带用户输入计算器构建及问题排查求助

基础计算器程序问题求助

我已经为此折腾了数小时,仍未解决这款基础计算器的以下问题:

  1. 终端中用户输入不可见,原因是什么?
  2. 程序运行不符合预期:
    • 当触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:40:18