目录
读取输入
标准输入流:System,in
Scanner in = new Scanner(System.in);
通过以上构造器就可以使用Scanner类的各种方法了。
nextLine方法:读取一行的输入
System.out.print("What is your name?");
String name = in.nextLine();
在这里,使用nextLine方法是因为在输入行中有可能包含空格。要想读取一个单词(以空白符作为分隔符),可以调用
String firstName = in.next();
要想读取一个整数,就调用nextInt方法
System.out.print("How old are you?");
int age = in.nextInt();
与此类似,要想读取下一个浮点数,就调用nextDouble方法。
Scanner类定义在java.util包中。当使用的类不是定义在基本java.lang包中时,一定要使用import指令导入相应的包
- 注释:因为输入是可见的,所以Scanner类不适用于从控制台读取密码。Java6特别引入了Console类来实现这个目的。要想读取一个密码,可以使用下列代码:
Console cons = System.console();
String username = cons.readLine("User name:");
char[] passwd = cons.readPassword("Password:");
为了安全起见,返回的密码存放在一个字符数组中,而不是字符串中。在对密码处理完成之后,应该马上用一个填充值覆盖数组元素。
采用Console对象处理输入不如采用Scanner方便。必须每次读取一行输入,而没有能够读取单个单词或数值的方法。
java.util.Scanner
Scanner(InputStream in) | 用给定的输入流创建一个Scanner对象 |
String nextLine() | 读取输入的下一行内容 |
String next() | 读取输入的下一个单词(以空格作为分隔符) |
int nextInt() double nextDouble() | 读取并转换下一个表示整数或浮点数的字符序列 |
boolean hasNext() | 检测输入中是否还有其他单词 |
boolean hasNextInt() boolean hasNextDouble() | 检测是否还有下一个表示整数或浮点数的字符序列 |
java.lang.System
static Console console()
如果可以进行交互,就返回一个Console对象通过控制台窗口与用户交互,否则返回null。对于任何一个在控制台窗口启动的程序,都可使用Console对象。否则,是否可用取决于所使用的系统。
java.io.Console
static char[] readPassword(String prompt,Object…args)
static String readLine(String prompt,Object…args)
显示字符串prompt(提示符)并读取用户输入,直到输入行结束。args参数可以用来提供格式参数。
格式化输出
可以使用语句System.out.print(x)将数值x输入到控制台。这条命令将以x的类型所允许的最大非0数位个数打印输出x。
double x = 10000.0 / 3.0;
System.out.print(x);
打印
3333.3333333333335
如果希望显示美元,美分数,这就会有问题。
因此,可以使用C语言函数库中的printf方法。
System.out.printf("%8.2f" , x);
会以一个字段宽度(field width)打印x:这包括8个字符,另外精度为小数点后2个字符。这就会打印一个前导空格和7个字符,如下所示:
3333.33
可以为printf提供多个参数,例如:
System.out.printf("Hello , %s.Next year , you'll be %d" , name , age);
每一个以%字符开始的格式说明符都用相应的参数替换。格式说明符尾部的转换符指示要格式化的数值类型:f表示浮点数,s表示字符串,d表示十进制整数。
printf的转换符
转换符 | 类型 | 示例 |
d | 十进制整数 | 159 |
x | 十六进制整数 | 9f |
o | 八进制整数 | 237 |
f | 定点浮点数 | 15.9 |
e | 指数浮点数 | 1.59e+01 |
g | 通用浮点数(e和f中较短的一个) | — |
a | 十六进制浮点数 | 0x1.fccdp3 |
s | 字符串 | Hello |
c | 字符 | H |
b | 布尔 | true |
h | 散列码 | 42628b2 |
tx或Tx | 日期时间(T强制大写) | 已经过时,应当改为使用java.time类 |
% | 百分号 | % |
n | 与平台有关的行分隔符 | — |
用于printf的标志 | ||
标志 | 目的 | 示例 |
+ | 打印正数和负数的符号 | +3333.33 |
空格 | 在正数之前添加空格 | |3333.33| |
0 | 数字前面补0 | 003333.33 |
- | 左对齐 | |3333.33| |
( | 将负数括在括号内 | (3333.33) |
, | 添加分组分隔符 | 3,333.33 |
#(对于f格式) | 包含小数点 | 3,333. |
#(对于x或0格式) | 添加前缀0x或0 | 0xcafe |
$ | 指定要格式化的参数索引。例如%1$d %1$x将以十进制和十六进制格式打印第一个参数 | 159 9F |
< | 格式化前面说明的数值。例如:%d%<x将以十进制和十六进制打印同一个数值 | 159 9F |
例如:
System.out,printf("%,.2f" , 10000.0/3.0);
打印
3,333.33
可以使用多个标志,例如,"% , ( .2f会使用分组分隔符并将负数括在括号内。
- 注释:可以使用s转换符格式化任意的对象。对于实现了Formattable接口的任意对象,将调用这个对象的formatTo方法;否则调用toString方法将这个对象转换成为字符串。
可以使用静态的String.format方法创建一个格式化的字符串,而不打印输出:
String message = String.format("Hello , %s , Next year , you'll be %d" , name , age);
日期和时间的转换符
转化符 | 类型 | 示例 |
c | 完整的日期和时间 | Mon Feb 09 18:05:19 PST2015 |
F | ISO 8601 日期 | 2015-02-09 |
D | 美国格式的日期(月/日/年) | 02/09/2015 |
T | 24小时时间 | 18:05:19 |
r | 12小时时间 | 06:05:19 pm |
R | 24小时时间,没有秒 | 18:05 |
Y | 4位数字的年(前面补零) | 2015 |
y | 年的后两位数字(前面补零) | 15 |
C | 年的前两位数字(后面补零) | 20 |
B | 月的完整拼写 | February |
b或h | 月的缩写 | Feb |
m | 两位数字的月(前面补零) | 02 |
d | 两位数字的日(前面补零) | 09 |
e | 两位数字的日(前面不补零) | 9 |
A | 星期几的完整拼写 | Monday |
a | 星期几的缩写 | Mon |
j | 三位数的年中第几天(前面补零),在001到366之间 | 069 |
H | 两位数字的小时(前面补零),在0到23之间 | 18 |
k | 两位数字的小时(前面不补零),在0到23之间 | 18 |
I | 两位数字的小时(前面补零),在01到12之间 | 06 |
L | 两位数字的小时(前面不补零),在1到12之间 | 6 |
M | 两位数字的分钟(前面补零) | 05 |
S | 两位数字的秒(前面补零) | 19 |
L | 三位数字的毫秒(前面补零) | 047 |
N | 九位数字的毫秒(前面补零) | 047000000 |
P | 上午或下午的标志 | pm |
z | 从GMT起,RFC 822数字位移 | -0800 |
Z | 时区 | PST |
s | 从格林尼治时间1970-01-01 00:00:00起的秒数 | 1078884319 |
Q | 从格林尼治时间1970-01-01 00:00:00起的毫秒数 | 1078884319047 |
例如:
System.out.printf("%tc" , new Date());
这条语句将用下面的格式打印当前日期和时间:
Mon Feb 09 18:05:19 PST 2015
某些格式只给出了指定日期的部分信息。例如,只有日期或月份。如果需要多次提供日期来分别格式化每一部分就太笨拙了。为此,可以用一个格式字符串指示要格式化的参数索引。索引必须紧跟在%后面,并以$终止。
例如:
System.out.printf("%1$s %2$tB %2$te , %2$tY" , "Due date:" , new Date());
会打印
Due date: February 9 , 2015
还可以选择使用<标志。它指示前面格式说明中的参数将被再次使用。也就是说,以下语句将产生与前面语句同样的输出结果:
System.out.printf("%s %tB %<te , %<tY" , "Due date:" , new Date());
- 警告:参数索引值从1开始,而不是从0开始,%1$...对第1个参数格式化。这就避免了与0标志混淆。
- 注释:数字和日期的格式化规则是特定于本地化环境的。例如,在德国,分组分隔符是点号不是逗号,另外Monday被格式化为Montag。
文件输入与输出
要想读取一个文件,需要构造一个Scanner对象,如下所示:
Scanner in = new Scanner(Path.of("myfile.txt") , StandardCharsets.UTF_8);
如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加一个额外的反斜杠转义:"c:\\mydirectory\\myfile.txt"。
- 注释:在这里指定了UTF-8字符编码,这对于互联网上的文件很常见(不过并不是普遍适用)。读取一个文本文件时,要知道它的字符编码。如果省略字符编码,则会使用运行这个Java程序的机器的“默认编码”。这不是一个好主意,如果在不同的机器上运行这个程序,可能会有不同的表现。
现在,就可以利用前面介绍的任何一个Scanner方法对文件进行读取。
要想写入文件,就需要构造一个PrintWriter对象。在构造器中,需要提供文件名和字符编码:
PrintWriter out = new PrintWriter("myfile.txt" , StandardCharsets.UTF_8);
如果文件不存在,创建该文件。可以像输出到System.out一样使用print、println、以及printf命令。
- 警告:可以构造一个带有字符串参数的Scanner,但这个Scanner会把字符串解释为数据,而不是文件名。例如,如果调用:
Scanner in = new Scanner("myfile.txt");//ERROP?
这个Scanner会将参数看作包含10个字符('m'、'y'、'f'等)的数据。这可能不是我们原本想要的。
- 注释:当指定一个相对文件名时,例如,"myfile.txt""mydirectory/myfile.txt"或"../myfile.txt",文件位于相对于java虚拟机启动目录的位置。如果在命令行方式下执行以下命令启动程序:
java MyProg
启动目录就是命令解释器的当前目录。然而,如果使用集成开发环境,那么启动目录将由IDE控制。可以使用下面的调用找到这个目录的位置:
String dir = System.getProperty("user.dir");
如果觉得定位文件太麻烦,可以考虑使用绝对路径名,例如:"c:\\mydirectory\\myfile.txt"或者"/home/me/mydirectory/mufile.txt"。
访问文件与使用System.in和System.out一样容易。要记住一点:如果用一个不存在的文件构造一个Scanner,或者用一个无法创建的文件名构造一个PrintWriter,就会产生异常。Java编译器认为这些异常比“被零除”异常更严重。只需要告诉编译器:你已经知道有可能出现“输入/输出”异常。这需要在main方法中使用throws子句标记,如下所示:
public static void main(String[] args) throws IOException{
Scanner in = new Scanner(Path.of("myfile.txt") , StandardCharsets.UTF_8);
…
}
- 注释:当采用命令运行方式启动一个程序时,可以利用shell的重定向语法将任意文件关联到System.in和System.out:
java MyProg<myfile,txt>output.txt
这样,就不必担心处理IOException异常了。
java.util.Scanner
Scanner(Path p , String encoding)
构造一个使用给定字符编码从给定路径读取数据的Scanner。
Scanner(String data)
构造一个从给定字符串读取数据的Scanner。
java.io,PrintWriter
PrintWriter(String fileName)
构造一个将数据写入文件的PrintWriter。文件名由参数指定。
java.nio.file.Path
static Path of(String pathname)
根据给定的路径名构造一个Path。
print、printf、println的区别
1、功能不同
1、print:将信息显示在命令窗口中,输出光标定位在最后一个字符之后。
2、printf:将信息进行格式化显示在命令窗口中,输出光标定位在最后一个字符之后。
3、println:将信息显示在命令窗口中,输出光标换行定位在下一行开头。
2、语法不同
print:Print("\n ") = Println(" ")。
printf:System.out.println(" b");
println:System.out.print(" ASD\n"); = System.out.println(" ASD")
3、特点不同
1、print:是需求输出的一系列参数, 其个数务必与式样化字符串所阐明的输出参数个数一样多, 各参数之间用","分开。
2、printf:式样化规定字符, 以"%"开端, 后跟一个或几个规定字符, 用来确定输出内容式样。
3、println:从右到左压栈,然后将先读取放到栈底,最后读取的放在栈顶,处理时候是从栈顶开始的。