Java5:Java输入输出:让程序和世界对话
目录写在前面一、输出让程序开口说话1.1 三种输出方式1.2 格式化输出详解二、输入让程序学会倾听2.1 Scanner的基本用法2.2 Scanner的常用方法2.3 一个容易踩的坑三、多组输入处理批量数据3.1 使用hasNext系列方法3.2 实际应用场景四、实战猜数字游戏4.1 游戏规则4.2 代码实现4.3 代码亮点分析4.4 运行效果演示五、总结与展望写在前面经过前面几篇文章的学习我们已经掌握了Java的基本语法、数据类型、运算符和流程控制。但仔细想想我们目前写的程序都有一个共同的特点数据都是写死在代码里的。变量赋值靠手写条件判断靠预设——这样的程序就像一个自言自语的人永远不知道外界发生了什么。今天这篇文章我们来学习Java的输入输出。掌握了这部分内容你的程序就能真正和用户对话了既能向用户展示信息也能接收用户的指令和数据。一、输出让程序开口说话1.1 三种输出方式Java提供了三种向控制台输出信息的方式它们各有特点System.out.println(带换行的输出); // 输出后自动换行 System.out.print(不带换行的输出); // 输出后不换行 System.out.printf(格式化输出: %d, 100); // 类似C语言的printf核心区别println输出内容后自动追加一个换行符相当于print\nprint输出内容后不换行下次输出会紧跟在后面printf支持格式化字符串可以精确控制输出格式来看一个对比的例子System.out.print(第一行); System.out.print(还在第一行); System.out.println(终于换行了); System.out.println(新的一行); // 输出结果 // 第一行还在第一行终于换行了 // 新的一行1.2 格式化输出详解printf的格式化能力非常强大它的基本语法是System.out.printf(格式字符串, 参数1, 参数2, ...);格式字符串中以%开头的占位符会被后面的参数依次替换。下表列出了常用的格式转换符转换符说明示例代码输出结果%d十进制整数%d, 100100%x十六进制整数%x, 255ff%o八进制整数%o, 100144%f浮点数%f, 3.143.140000%.2f保留两位小数的浮点数%.2f, 3.141593.14%e科学计数法%e, 100.01.000000e02%s字符串%s, 你好你好%c字符%c, AA%b布尔值%b, 5 3true实用技巧 格式化输出不需要死记硬背用到的时候查阅资料就可以了。但有几个高频用法值得记住// 控制小数位数 System.out.printf(价格: %.2f 元\n, 99.999); // 价格: 100.00 元 // 输出百分号 System.out.printf(完成度: %.1f%%\n, 87.5); // 完成度: 87.5% // 对齐和补位 System.out.printf(编号: %05d\n, 42); // 编号: 00042二、输入让程序学会倾听如果说输出是程序的嘴巴那输入就是程序的耳朵。Java中最常用的输入工具是Scanner类。2.1 Scanner的基本用法使用Scanner需要三步导入、创建、读取。import java.util.Scanner; // 第一步导入Scanner类 public class InputDemo { public static void main(String[] args) { Scanner sc new Scanner(System.in); // 第二步创建Scanner对象 // 第三步读取不同类型的数据 System.out.println(请输入你的姓名); String name sc.nextLine(); // 读取一行字符串 System.out.println(请输入你的年龄); int age sc.nextInt(); // 读取整数 System.out.println(请输入你的工资); double salary sc.nextDouble(); // 读取浮点数 System.out.println(\n 你的个人信息 ); System.out.println(姓名 name); System.out.println(年龄 age); System.out.println(工资 salary); sc.close(); // 关闭Scanner释放资源 } }运行效果请输入你的姓名 张三 请输入你的年龄 25 请输入你的工资 8500.50 你的个人信息 姓名张三 年龄25 工资8500.502.2 Scanner的常用方法方法返回值类型说明nextLine()String读取一整行包含空格next()String读取下一个单词遇空格停止nextInt()int读取一个整数nextDouble()double读取一个浮点数nextBoolean()boolean读取一个布尔值hasNextInt()boolean判断下一个输入是否为整数hasNextDouble()boolean判断下一个输入是否为浮点数2.3 一个容易踩的坑问题 如果在读取整数之后紧接着读取字符串可能会遇到跳过输入的现象。Scanner sc new Scanner(System.in); System.out.println(请输入年龄); int age sc.nextInt(); System.out.println(请输入姓名); String name sc.nextLine(); // 这里可能直接跳过 System.out.println(年龄 age 姓名 name); sc.close();为什么会这样当你输入年龄后按下回车nextInt()只读取了数字但回车产生的换行符仍然留在缓冲区中。紧接着的nextLine()会直接读取到这个残留的换行符导致看起来像是跳过了输入。解决方案有两种方案一 在读取整数后额外调用一次nextLine()来消耗掉换行符。int age sc.nextInt(); sc.nextLine(); // 消耗掉残留的换行符 String name sc.nextLine();方案二 统一使用nextLine()读取然后手动转换成需要的类型。int age Integer.parseInt(sc.nextLine()); String name sc.nextLine();第二种方案更加稳健推荐在实际开发中使用。三、多组输入处理批量数据在实际编程中我们经常需要处理数量不确定的输入数据。比如在线评测系统中题目往往不会告诉你具体有多少个测试用例你需要一直读取直到输入结束。3.1 使用hasNext系列方法Scanner提供了hasNext系列方法来判断是否还有下一个输入import java.util.Scanner; public class MultiInputDemo { public static void main(String[] args) { Scanner sc new Scanner(System.in); int sum 0; int count 0; // 持续读取直到没有更多输入 while (sc.hasNextInt()) { int num sc.nextInt(); sum num; count; } System.out.println(总和 sum); System.out.println(个数 count); System.out.println(平均值 (count 0 ? (double)sum / count : 0)); sc.close(); } }运行示例10 20 30 40 ^D 总和100 个数4 平均值25.0结束输入的快捷键Windows系统按Ctrl Z然后回车Linux/Mac系统按Ctrl D3.2 实际应用场景多组输入最常见的应用场景是在线评测系统。比如一道题目要求输入若干行每行两个整数计算它们的和。Scanner sc new Scanner(System.in); while (sc.hasNextInt()) { int a sc.nextInt(); int b sc.nextInt(); System.out.println(a b); } sc.close();这种写法简洁高效能够处理任意数量的输入行是OJ刷题的标配写法。四、实战猜数字游戏现在我们把学到的所有知识串起来实现一个经典的猜数字游戏。4.1 游戏规则程序随机生成一个1到100之间的整数玩家输入猜测的数字如果猜小了提示低了如果猜大了提示高了如果猜对了提示猜对了并结束游戏4.2 代码实现import java.util.Random; import java.util.Scanner; public class GuessNumberGame { public static void main(String[] args) { Random random new Random(); Scanner sc new Scanner(System.in); // 生成1到100之间的随机数 int target random.nextInt(100) 1; int attempts 0; System.out.println( 猜数字游戏 ); System.out.println(我已经想好了一个1~100之间的数字来猜猜看吧); while (true) { System.out.print(请输入你的猜测); // 检查输入是否合法 if (!sc.hasNextInt()) { System.out.println(请输入有效的整数); sc.next(); // 消耗掉无效输入 continue; } int guess sc.nextInt(); attempts; if (guess target) { System.out.println(低了再大一点); } else if (guess target) { System.out.println(高了再小一点); } else { System.out.println(恭喜你猜对了); System.out.println(你一共猜了 attempts 次。); break; } } sc.close(); } }4.3 代码亮点分析输入校验使用hasNextInt()检查输入是否为整数避免程序因非法输入而崩溃尝试次数统计记录玩家猜了多少次增加游戏的反馈感无限循环break直到猜对才退出符合游戏逻辑4.4 运行效果演示 猜数字游戏 我已经想好了一个1~100之间的数字来猜猜看吧 请输入你的猜测50 低了再大一点 请输入你的猜测75 高了再小一点 请输入你的猜测63 低了再大一点 请输入你的猜测69 高了再小一点 请输入你的猜测66 恭喜你猜对了 你一共猜了 5 次。五、总结与展望今天我们学习了Java中输入输出的核心知识输出方面println带换行的输出print不带换行的输出printf格式化输出灵活控制显示格式输入方面Scanner的基本用法nextInt()、nextDouble()、nextLine()输入类型不匹配时的处理方法多组输入的循环读取模式实战方面实现了完整的猜数字游戏综合运用了输入输出、随机数生成、循环控制等知识掌握了输入输出你的程序就不再是一个封闭的系统而是能够与用户交互的活的程序。从下一篇开始我们将进入Java编程的核心领域——方法学习如何把代码组织得更加模块化和可复用。期待与你继续同行。