当前位置: 首页 > news >正文

从ATM取款机到游戏菜单:用Java循环和Scanner打造你的第一个命令行交互程序(附完整代码)

从ATM取款机到游戏菜单:用Java循环和Scanner打造你的第一个命令行交互程序

当你第一次学习Java基础语法时,课本上的例子往往让人提不起兴趣——打印星星、计算数字,这些简单的练习很难让你感受到编程的乐趣。但你知道吗?这些看似枯燥的循环和条件语句,正是构建交互式程序的基础。本文将带你跳出课本习题,用while循环、Scanner输入和简单的控制逻辑,打造一个完整的命令行交互程序。

1. 为什么需要交互式程序?

在真实开发中,程序很少是单向执行的。想想你每天使用的软件:ATM机需要你输入密码和金额,游戏菜单需要你选择角色和装备,学生管理系统需要查询和修改数据。这些场景都有一个共同点——程序需要根据用户输入做出不同响应,并且持续运行直到用户主动退出

传统课本上的循环练习(如打印10x10的星号矩阵)虽然能教会你语法,但缺乏真实感。让我们换个思路,用循环结构来实现这些实用场景:

// 传统练习:打印星号矩阵 for(int i=0; i<10; i++){ for(int j=0; j<10; j++){ System.out.print("*"); } System.out.println(); } // 交互式程序:游戏菜单框架 while(true){ showMenu(); int choice = getUserInput(); processChoice(choice); }

前者只是机械地重复输出,后者却能创建真正的用户对话。这就是我们要追求的学习方式——用基础语法解决实际问题

2. 构建交互程序的核心组件

2.1 循环结构的选择

Java提供了三种主要的循环结构,每种适合不同场景:

循环类型特点适用场景
while先判断条件后执行不确定循环次数时(如菜单系统)
do-while先执行一次再判断条件至少需要执行一次时(如密码重试)
for明确循环次数遍历数组、固定次数的操作

对于交互程序,while循环是最自然的选择:

boolean running = true; while(running){ // 显示菜单 // 获取输入 // 处理逻辑 // 根据输入可能设置running=false }

2.2 Scanner输入处理

java.util.Scanner是处理控制台输入的利器。关键方法包括:

  • nextInt(): 读取整数
  • nextLine(): 读取整行文本
  • nextDouble(): 读取浮点数

注意:混合使用不同Scanner方法时,要注意换行符的处理。建议在读取数字后调用nextLine()消耗换行符。

2.3 流程控制技巧

  • break: 立即退出当前循环
  • continue: 跳过本次循环剩余部分
  • return: 从方法返回(如果在循环中)

这些控制语句能让你更灵活地管理程序流程。

3. 实战:游戏角色菜单系统

让我们用上述知识构建一个简易的游戏角色管理系统。功能包括:

  1. 查看角色属性
  2. 装备武器
  3. 使用道具
  4. 退出游戏

3.1 基础框架搭建

import java.util.Scanner; public class GameMenuSystem { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); boolean gameRunning = true; // 角色初始属性 String characterName = "冒险者"; int health = 100; String weapon = "木剑"; int potions = 3; while(gameRunning) { System.out.println("\n=== 角色菜单 ==="); System.out.println("1. 查看角色属性"); System.out.println("2. 装备武器"); System.out.println("3. 使用道具"); System.out.println("4. 退出游戏"); System.out.print("请选择操作: "); int choice; try { choice = scanner.nextInt(); scanner.nextLine(); // 消耗换行符 } catch(Exception e) { System.out.println("输入无效,请输入数字1-4"); scanner.nextLine(); // 清除错误输入 continue; } // 处理用户选择 switch(choice) { case 1: // 查看属性逻辑 break; case 2: // 装备武器逻辑 break; case 3: // 使用道具逻辑 break; case 4: gameRunning = false; break; default: System.out.println("无效选择,请重新输入"); } } System.out.println("游戏结束,再见!"); scanner.close(); } }

3.2 完善各功能模块

查看角色属性

System.out.println("\n=== 角色属性 ==="); System.out.println("名称: " + characterName); System.out.println("生命值: " + health); System.out.println("当前武器: " + weapon); System.out.println("道具数量: " + potions);

装备武器

System.out.println("\n可选择的武器:"); System.out.println("1. 铁剑 (攻击力+10)"); System.out.println("2. 长弓 (攻击力+15)"); System.out.println("3. 法杖 (攻击力+20)"); System.out.print("选择要装备的武器: "); int weaponChoice = scanner.nextInt(); scanner.nextLine(); // 消耗换行符 switch(weaponChoice) { case 1: weapon = "铁剑"; break; case 2: weapon = "长弓"; break; case 3: weapon = "法杖"; break; default: System.out.println("无效选择,保持原武器"); } System.out.println("已装备: " + weapon);

使用道具

if(potions > 0) { System.out.println("使用道具,生命值恢复30点"); health += 30; potions--; System.out.println("剩余道具: " + potions); System.out.println("当前生命值: " + health); } else { System.out.println("没有可用道具了!"); }

3.3 异常处理增强

良好的交互程序应该能处理各种异常输入:

// 在获取数字输入的地方添加try-catch try { choice = scanner.nextInt(); scanner.nextLine(); // 消耗换行符 } catch(Exception e) { System.out.println("输入无效,请输入数字1-4"); scanner.nextLine(); // 清除错误输入 continue; }

4. 扩展思路:学生成绩查询系统

同样的框架可以轻松改造成其他实用程序。比如学生成绩查询系统:

import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class StudentGradeSystem { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); boolean systemRunning = true; // 模拟学生数据 Map<String, Integer> grades = new HashMap<>(); grades.put("张三", 85); grades.put("李四", 92); grades.put("王五", 78); while(systemRunning) { System.out.println("\n=== 学生成绩管理系统 ==="); System.out.println("1. 查询成绩"); System.out.println("2. 添加学生"); System.out.println("3. 修改成绩"); System.out.println("4. 退出系统"); System.out.print("请选择操作: "); int choice = scanner.nextInt(); scanner.nextLine(); // 消耗换行符 switch(choice) { case 1: System.out.print("输入学生姓名: "); String name = scanner.nextLine(); if(grades.containsKey(name)) { System.out.println(name + "的成绩是: " + grades.get(name)); } else { System.out.println("找不到该学生"); } break; case 2: System.out.print("输入新学生姓名: "); String newName = scanner.nextLine(); System.out.print("输入成绩: "); int newGrade = scanner.nextInt(); scanner.nextLine(); grades.put(newName, newGrade); System.out.println("添加成功"); break; case 3: System.out.print("输入要修改的学生姓名: "); String updateName = scanner.nextLine(); if(grades.containsKey(updateName)) { System.out.print("输入新成绩: "); int updatedGrade = scanner.nextInt(); scanner.nextLine(); grades.put(updateName, updatedGrade); System.out.println("修改成功"); } else { System.out.println("找不到该学生"); } break; case 4: systemRunning = false; break; default: System.out.println("无效选择"); } } System.out.println("系统已退出"); scanner.close(); } }

这个例子展示了如何用相同的循环和输入处理框架,构建完全不同功能的交互程序。

5. 最佳实践与常见陷阱

5.1 交互程序设计原则

  1. 清晰的用户引导:每个步骤都要明确告诉用户可以做什么
  2. 一致的交互模式:保持输入输出风格一致
  3. 健壮的错误处理:预料可能的错误输入并妥善处理
  4. 简洁的界面:避免信息过载,合理分页

5.2 常见问题与解决方案

问题1:Scanner输入混乱

  • 现象:混合使用nextInt()和nextLine()时出现跳过输入
  • 解决:在nextInt()后立即调用nextLine()消耗换行符
int num = scanner.nextInt(); scanner.nextLine(); // 消耗换行符

问题2:无限循环

  • 现象:程序无法退出,一直循环
  • 解决:确保有明确的退出条件,并测试所有分支
while(running) { // ... if(choice == EXIT_OPTION) { running = false; // 确保这个条件能被触发 } }

问题3:代码重复

  • 现象:相似的处理逻辑在多处重复
  • 解决:将重复代码提取为方法
private static int getMenuChoice(Scanner scanner, int maxOption) { while(true) { try { int choice = scanner.nextInt(); scanner.nextLine(); if(choice >= 1 && choice <= maxOption) { return choice; } System.out.println("请输入1-" + maxOption + "之间的数字"); } catch(Exception e) { System.out.println("请输入有效的数字"); scanner.nextLine(); } } }

6. 进一步优化方向

6.1 添加更多功能

  • 保存/加载数据到文件
  • 添加密码验证功能
  • 实现更复杂的业务逻辑

6.2 改进用户体验

  • 添加颜色输出(使用ANSI转义码)
  • 实现多级菜单系统
  • 添加ASCII艺术标题
public static void printTitle() { System.out.println(" ____ _ _ _ _ "); System.out.println(" / ___|| |_ __ _| |_(_)___| |"); System.out.println(" \\___ \\| __/ _` | __| / __| |"); System.out.println(" ___) | || (_| | |_| \\__ \\_|"); System.out.println(" |____/ \\__\\__,_|\\__|_|___(_)"); System.out.println(); }

6.3 代码结构优化

  • 使用面向对象设计,将不同功能封装到类中
  • 使用枚举定义菜单选项
  • 实现命令模式处理用户输入
enum MenuOption { VIEW_STATS("查看属性", 1), EQUIP_WEAPON("装备武器", 2), USE_ITEM("使用道具", 3), EXIT("退出游戏", 4); private String description; private int code; // 构造函数、getter方法等 } // 使用示例 for(MenuOption option : MenuOption.values()) { System.out.println(option.getCode() + ". " + option.getDescription()); }
http://www.jsqmd.com/news/817733/

相关文章:

  • OpenClaw自动化框架:从零构建RPA与AI Agent的集成开发环境
  • PingAPi:AI 驱动的企业级低代码 API 平台,5.0 版本更新亮点多!
  • 开源虾类养殖监控系统:ESP32与MQTT物联网技术实践
  • Nibble:用3000行C语言编写的系统编程语言,功能强大但编译有栈溢出风险!
  • 对比按量计费与Token Plan套餐如何根据用量选择更优成本方案
  • 上海全屋定制工厂怎么选?莫干山板材全屋定制避坑指南与工厂筛选逻辑 - 资讯焦点
  • 微信公众号文章抓取与格式转换工具:从HTML解析到Markdown输出的技术实现
  • 想都是问题,做才是答案
  • 量子误差缓解技术与贝叶斯方法在NISQ时代的应用
  • 解决 Claude Code 插件频繁封号与 Token 不足的稳定替代方案
  • 手机和手机怎么共享屏幕 手机控制手机软件推荐
  • 基于国家代码的动态配置切换:cc-switch库的设计原理与实战应用
  • 山东知名玻尿酸机构排行:技术与合规实力对比 - 资讯焦点
  • Eyes up, Stay sharp
  • 快速开发AI应用原型时Taotoken多模型切换的价值
  • 从零到一:OneNET物联网平台快速接入与双向通信实战
  • 包头招聘网站哪个靠谱:秒聘网正规靠谱 - 17329971652
  • 使用Python自动化CATIA:pycatia终极指南 [特殊字符]
  • EasyInstruct:模块化指令工程框架,让大模型精准执行复杂任务
  • 别再只盯着Mobile SDK了!大疆Onboard SDK实战:用ROS在Matrice 300上实现自主巡检(附避坑指南)
  • 包头招聘网站哪个岗位多:秒聘网职源海量 - 13724980961
  • 使用 Hermes Agent 框架并配置 Taotoken 作为自定义模型供应商
  • 铸铝门厂家怎么选?五大靠谱品牌推荐(2026最新) - 资讯焦点
  • C#架构师实战:构建确定性分布式系统与智能体编排的核心设计
  • 从3D打印机到雕刻机:A4988驱动模块的微步进模式详解与实战配置
  • 基于MCP协议构建AI安全访问PostgreSQL数据库的实战指南
  • STM32实战:从零搭建智能温湿度监控与本地报警系统
  • 【工作流】工作流
  • 告别枯燥界面:用Qt自定义控件打造游戏化HMI(汽车仪表+雷达扫描实战)
  • 山东优质双眼皮机构排行 5家正规专科实力盘点 - 资讯焦点