在程序运行中要获取用户的输入数据来控制程序,我们要使用到 java.util 包中的 Scanner 类。当然 Java 中还可以使用其他的输入方式,但这里主要讲解 Scanner 类方法。关于 Scanner 类我们可以直接通过了解它的 API 文档来使用它。
Scanner 类定义在 java.util 包中。当使用的类不是定义在基本 java.lang 包中时,一定要使用 import 关键字导入相应的包。
要通过控制台进行输入,首先需要构造一个 Scanner 对象,并与 “标准输入流” System.in 关联。
Scanner in = new Scanner(System.in);
构造完对象之后,我们就可以使用 Scanner 类的各种方法来实现输入操作了。
使用 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串。在读取前我们一般需要 使用 hasNext 与 hasNextLine 判断缓冲区是否有输入的数据,返回值为布尔值。
1、String next()
读取输入的第一个单词(以空格作为分隔符)
String str = in.next();
接收到一个数据之后,空白之后的其他内容即将继续存在缓存中。一定要将缓存区的内容处理,否则会影响后面的输入接收。
2、String nextLine()
读取输入的一行内容。
String str = in.nextLine();
如果要输入整型或浮点型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法(返回值为布尔类型)进行输入的类型验证,再使用 nextXxx() 来读取。
想要读取一个整数,可以调用 nextInt() 方法。
int i = in.nextInt();
与此类似,想要读取浮点数可以使用 nextDouble() 方法。更多方法请自行阅读 Scanner 类方法。
因为输入是可见的,所以 Scanner 类不适用于从控制台读取密码。我们可以使用 Console 类来实现这个目的。
Console cons = System.console();
String username = cons.readLine("User name: ");
char[] passwd = cons.readPassword("PassWord: ");
为了安全起见,返回的密码存放在一个一维数组中,而不是字符串中。在对密码进行处理之后,应该马上用一个填充值覆盖数组元素。
例:实现获取用户名和密码,并将其打印出来。
import java.io.Console;
public class TestConsole {
public static void main(String[] args) {
Console cons = System.console();
String username = cons.readLine("User name: ");
char[] passwd = cons.readPassword("PassWord: ");
System.out.println("User name: " + username);
System.out.println("PassWord: " + String.valueOf(passwd));
}
}
运行结果
注意:java.io.Console 只能用在标准输入、输出流未被重定向的原始控制台中使用,在 Eclipse 或者其他 IDE 的控制台无法使用。
在控制台输入数据时,如果输入的内容类型与接收预设的类型不一致,将抛出错误并终止程序。可以其他方法检测或跳过可能出错的语句。
如果使用 hasNextXx() 方法判断输入的类型,用户输入的内容还是存在缓存中,直到将数据接收或程序终止。可以通过 nextLine() 方法将缓存中的内容接收,以达到清空缓冲区中的内容。也可以重新构造原来的 Scanner 对象。
import java.util.*;
public class First {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// 从键盘接收数据
int i = 0;
float f = 0.0f;
scan = new Scanner(System.in);
System.out.print("输入整数:");
if (scan.hasNextInt()) {
// 判断输入的是否是整数
i = scan.nextInt();
// 接收整数
System.out.println("整数数据:" + i);
} else {
// 输入错误的信息
System.out.println("输入的不是整数!");
scan.nextLine(); // 处理缓存区内容
//或者 scan = new Scanner(System.in);
}
System.out.print("输入小数:");
if (scan.hasNextFloat()) {
// 判断输入的是否是小数
f = scan.nextFloat();
// 接收小数
System.out.println("小数数据:" + f);
} else {
// 输入错误的信息
System.out.println("输入的不是小数!");
}
scan.close();
}
}
控制台输出可以使用 System.out.print() ,System.out.printf() , System.out.println() 等方法。
输出格式化数字可以使用 printf() 和 format() 方法。
使用 System.out.printf() 方法在控制台上显示格式化输出。
System.out.printf(format, item1, item2, ..., itemn);
这里的 format 是指一个由子串和格式说明符构成的字符串。格式说明符指定每个条目应该如何显示。这里的条目可以是数值、字符、布尔值或字符串。简单的格式说明符是以百分号 (%) 开头的转换码。
转换符 | 类型 | 举例 |
---|---|---|
d | 十进制整数 | 159 |
x | 十六进制整数 | 9f |
o | 八进制整数 | 237 |
f | 定点浮点数 | 15.9 |
e | 指数浮点数 | 1.59e+01 |
g | 通用浮点数 | - |
a | 十六进制浮点数 | 0x1.fccdp3 |
s | 字符串 | Hello |
c | 字符 | H |
b | 布尔 | True |
h | 散列码 | 42628b2 |
tx | 日期时间 | x见下 |
% | 百分号 | % |
n | 与平台有关的行分隔符 | - |
标志 | 目的 | 举例 |
---|---|---|
+ | 打印正数和负数的符号 | +3333.33 |
空格 | 在正数之前添加空格 | | 3333.33| |
0 | 数字前面补0 | 003333.33 |
- | 左对齐 | |3333.33 | |
( | 将负数括在括号内 | (3333.33) |
, | 添加分组分隔符 | 3,333.33 |
#(对于f格式) | 包含小数点 | 3333.33 |
#(对于x或0格式) | 添加前缀0x或0 | 0xcafe |
$ | 给定被格式化的参数索引。如%1$d将以十进制打印第一个参数 | |
< | 格式化前面说明的数值。如%d%
| |
在这里,使用以 t 开始,格式为 tx,x代表的内容如下表:
转换符 | 类型 | 举例 |
---|---|---|
c | 完整的日期和时间 | 周日 4月 19 11:51:37 CST 2020 |
F | ISO 8601 日期 | 2020-04-19 |
D | 美国格式的日期(月/日/年) | 04/19/20 |
T | 24小时时间 | 11:56:27 |
r | 12小时时间 | 11:57:05 上午 |
R | 24小时时间没有秒 | 11:56 |
Y | 4位数字的年 | 2020 |
y | 年的后两位数字 | 20 |
C | 年的前两位数字 | 20 |
B | 月的完整拼写 | February |
b或h | 月的缩写 | Feb |
m | 两位数字的月 | 04 |
d | 两位数字的日(前面补0) | 09 |
e | 两位数字的日(前面不补0) | 9 |
A | 星期几的完整拼写 | Monday |
a | 星期几的缩写 | Mon |
j | 三位数的年中的日子(前面补0),在001到366之间 | 069 |
H | 两位数字的小时(前面补0),0到23之间 | 12 |
k | 两位数字的小时(前面不补0),0到23之间 | 12 |
I(i的大写) | 两位数字的小时(前面补0),0到12之间 | 06 |
l(L的小写) | 两位数字的小时(前面不补0),0到12之间 | 6 |
M | 两位数字的分钟(前面补0) | 05 |
S | 两位数字的秒(前面补0) | 19 |
L | 三位数字的毫秒(前面补0) | 047 |
N | 九位数字的毫微秒(前面补0) | 020000000 |
P | 上午或下午的大写标志 | PM |
p | 上午或下午的小写标志 | am |
z | 从GMT起,RFC822数字位移 | +0800 |
Z | 时区 | CST |
s | 从格林威治时间1970-01-01 00:00:00 起的秒数 | 1587270316 |
Q | 从格林威治时间1970-01-01 00:00:00 起的毫秒数 | 1587270331450 |
Date date = new Date();
System.out.printf("%1$s %2$tB%2$te日, %2$tY","data:",date);
//输出结果为
data: 四月19日, 2020
索引必须紧跟在%后面,并以$终止。参数索引值从1开始,而不是从0开始。
同样还可以使用 < 标志。它指示前面格式说明中的参数将再次使用。
System.out.printf("%s %tB%
举例 | 输出 |
---|---|
%5c | 输出字符并在这个字符条目前面加4个空格 |
%6b | 输出布尔值,在false值前加一个空格,在true值前加两个空格 |
%5d | 输出整个条目,宽度至少为5.如果该条目的数字位数小于5,就在数字前面加空格.如果该条目的位数大于5,则自动增加宽度 |
%10.2f | 输出的浮点条目宽度至少为10,包括小数点、和小数点后两位数字.这样,给小数点前分配了7位数字. 如果该条目小数点前的位数小于7,就在数字前面加空格. 如果该条目小数点前的位数大于7,则自动增加宽度. |
%10.2e | 输出的浮点条目的宽度至少为10,包括小数点、小数点后面两位数字和指数部分.如果按科学计数法显示的数字位数小于10,就给数字前加空格 |
%12s | 输出的字符串至少为12个字符.如果该字符串条目小于12个字符,就在该字符串前加空格.如果该字符串条目多余12个字符,则自动增加宽度 |
例子
public class PrintfDemo {
public static void main(String[] args) {
System.out.printf("%5.6f",12345678.12345678);
System.out.println();
System.out.printf("%8.4f",1.12);
System.out.println();
System.out.printf("%-8.4f",1.12);
}
}
/*输出:
12345678.123457
1.1200
1.1200
*/
关于格式化 format() 方法请阅读 Java 学习笔记(七)–格式化字符串及格式化输出 。