其他分享
首页 > 其他分享> > 输入与输出

输入与输出

作者:互联网

输入与输出

读取输入

Scanner对象

将输出打印到“标准输出流”(即控制台窗口)是一件非常容易的事情,只要调用System.out.println即可。然而,读取“标准输入流”System.in就没有那么简单了。要想通过控制台进行输入,首先需要构造一个与“标准输入流”System.in关联的Scanner对象。

Scanner in = new Scanner(System.in);

nextline方法

现在,就可以使用Scanner类的各种方法读取输入了。例如,nextline方法将读取一行输入。

System.out.print("What is your name?");
String name = in.nextline();

next方法

在这里,使用nextLine方法是因为在输入行中有可能包含空格。要想读取一个单词(以空白符作为分隔符),可以调用

String firstName = in.next();

nextInt方法

要想读取一个整数,就调用nextInt方法。

System.out.print("How old are you?");
int age = in.nextInt();

nextDouble方法

与此类似,要想读取下一个浮点数,就调用nextDouble方法。

最后,在程序的最前面添加一行代码:

import java.util.*;

Scanner类定义在java.util包中。当使用的类不是定义在基本java.lang包中时,一定要使用import指令导入相应的包。

注释

因为输入是可见的,所以Scanner类不适用于从控制台读取密码。Java 6特别引入了Console类来实现这个目的。要想读取一个密码,可以使用下列代码:

Console cons = System.console(); 
String username = cons.readLine("User name:");
char[] passwd = cons.readPassword("Password:");

为安全起见,返回的密码存放在一个字符数组中,而不是字符串中。在对密码处理完成之后,应该马上用一个填充值覆盖数组元素。

采用Console对象处理输入不如采用Scanner方便。必须每次读取一行输入,而没有能够读取单个单词或数值的方法。

程序示例

import java .util.*;

public class HuangZiHanTest
{  
   public static void main(String[] args)
   {
	   Scanner huangzihan_in=new Scanner(System.in);
	   
	   System.out.println("你叫什么名字?");
	   String huangzihan_name=huangzihan_in.nextLine();
	   
	   System.out.println("你今年几岁?");
	   int huangzihan_age=huangzihan_in.nextInt();
	   
	   System.out.println("你多高?(m)");
	   double huangzihan_tall=huangzihan_in.nextDouble(); 
	   
	   System.out.println("你好,"+huangzihan_name+",今年你"+huangzihan_age+"岁,身高"+huangzihan_tall+"m。");
   }
}

运行结果

你叫什么名字?
黄子涵
你今年几岁?
27
你多高?(m)
1.77
你好,黄子涵,今年你27岁,身高1.77m。

格式化输出

Systen.out.print(x)

可以使用语句Systen.out.print(x)将数值x输出到控制台。这条命令将以x的类型所允许的最大非0数位个数打印输出x。例如:

double x = 10000.0/3.0;
System.out.print(x);

打印

3333.3333333333335

如果希望显示美元、美分数,这就会有问题。

程序示例

public class HuangZiHanTest
{  
   public static void main(String[] args)
   {
	   double huangzihan_x = 10000.0/3.0;
	   System.out.print(huangzihan_x);
   }
}

运行结果

3333.3333333333335

printf方法

在早期的Java版本中,格式化数值曾引起过一些争议。庆幸的是,Java 5沿用了C语言函数库中的printf方法。例如,调用

System.out.printf("%8.2f",x);

会以一个字段宽度(field
width)打印x:这包括8个字符,另外精度为小数点后2个字符。也就是说,这会打印一个前导的空格和7个字符,如下所示:

3333.33

程序示例

public class HuangZiHanTest
{  
   public static void main(String[] args)
   {
	   double huangzihan_x = 10000.0/3.0;
	   System.out.println(huangzihan_x);
	   System.out.println();
	   System.out.printf("%8.2f",huangzihan_x);  
   }
}

运行结果

3333.3333333333335

 3333.33

printf提供多个参数

可以为printf提供多个参数,例如:

System.out.printf("Hello,%s,Next year,you'll be %d",name,age);

每一个以%字符开始的格式说明符都用相应的参数替换。格式说明符尾部的转换符指示要格式化的数值的类型:f表示浮点数,s表示字符串,d表示十进制整数。表(用于printf的转换符)列出了所有转换符。

程序示例

import java .util.*;

public class HuangZiHanTest
{  
   public static void main(String[] args)
   {
	   Scanner huangzihan_in=new Scanner(System.in);
	   
	   System.out.println("你叫什么名字?");
	   String huangzihan_name=huangzihan_in.nextLine();
	   
	   System.out.println("你今年几岁?");
	   int huangzihan_age=huangzihan_in.nextInt();
	   
	   System.out.println("你多高?(m)");
	   double huangzihan_tall=huangzihan_in.nextDouble(); 
	   
	   System.out.println("你好,"+huangzihan_name+",今年你"+huangzihan_age+"岁,身高"+huangzihan_tall+"m。");
	   
	   System.out.printf("你好,%s,今年,你%d岁啦!",huangzihan_name,huangzihan_age);
   }
}

运行结果

你叫什么名字?
黄子涵
你今年几岁?
27
你多高?(m)
1.77
你好,黄子涵,今年你27岁,身高1.77m。
你好,黄子涵,今年,你27岁啦!

用于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强制大写) 已经过时
% 百分号 %
n 与平台有关的行分隔符 -

用于printf的标志

另外,还可以指定控制格式化输出外观的各种标志。表(用于printf的标志)列出了所有的标志。例如,逗号标志可以增加分组分隔符。即

System.out.printf("%,.2f",10000.0/3.0);

会打印

3,333.33

可以使用多个标志,例如,"%,(.2f"会使用分组分隔符并将负数括在括号内。

程序示例

public class HuangZiHanTest
{  
   public static void main(String[] args)
   {
	   double huangzihan_x = 10000.0/3.0;
	   System.out.println(huangzihan_x);
	   System.out.println();
	   System.out.printf("%8.2f",huangzihan_x);  
	   System.out.println();
	   System.out.printf("%,.2f",10000.0/3.0);
   }
}

运行结果

3333.3333333333335

 3333.33
3,333.33

用于printf的标志

image

注释

String.format方法

可以使用s转换符格式化任意的对象。对于实现了Formattable接口的任意对象,将调用这个对象的formatTo方法;否则调用toString方法将这个对象转换为字符串。

可以使用静态的String.format方法创建一个格式化的字符串,而不打印输出:

String message = String.format("Hello,%s.Next year,you'll be %d",name,age);

基于完整性的考虑,下面简略地介绍printf方法中日期与时间的格式化选项。不过你可能会在遗留代码中看到Date类和相关的格式化选项。这个格式包括两个字母,以t开始,以表(日期和时间的转换符)中的任意字母结束。

程序示例

import java .util.*;

public class HuangZiHanTest
{  
   public static void main(String[] args)
   {
	   Scanner huangzihan_in=new Scanner(System.in);
	   
	   System.out.println("你叫什么名字?");
	   String huangzihan_name=huangzihan_in.nextLine();
	   
	   System.out.println("你今年几岁?");
	   int huangzihan_age=huangzihan_in.nextInt();
	   
	   System.out.println("你多高?(m)");
	   double huangzihan_tall=huangzihan_in.nextDouble(); 
	   
	   System.out.println("你好,"+huangzihan_name+",今年你"+huangzihan_age+"岁,身高"+huangzihan_tall+"m。");
	   
	   System.out.printf("你好,%s,今年,你%d岁啦!",huangzihan_name,huangzihan_age);
	   System.out.println();
	   
	   String huangzihan_message = String.format("你好,%s.今年,你%d岁啦!",huangzihan_name,huangzihan_age);
	   System.out.println(huangzihan_message);
   }
}

运行结果

你叫什么名字?
黄子涵
你今年几岁?
27
你多高?(m)
1.77
你好,黄子涵,今年你27岁,身高1.77m。
你好,黄子涵,今年,你27岁啦!
你好,黄子涵.今年,你27岁啦!

打印当前的日期和时间

例如,

System.out.printf("%tc",new Date());

这条语句将用下面的格式打印当前的日期和时间:

Mon Feb 09 18:05:19 PST 2015

程序示例

import java.util.Date;

public class HuangZiHanTest
{  
   public static void main(String[] args)
   {
	   System.out.printf("%tc",new Date());
   }
}

运行结果

周六 7月 03 16:58:14 CST 2021

日期和时间的转换符

image

image

image

索引

从表(日期和时间的转换符)可以看到,某些格式只给出了指定日期的部分信息。例如,只有日期或月份。如果需要多次提供日期来分别格式化每一部分就太笨拙了。为此,可以用一个格式字符串指示要格式化的参数索引。索引必须紧跟在%后面,并以$终止。例如,

System.out.printf("%1$s %2$tB %2$te,%2$tY","Due date:",new Date());

会打印

Due date:February 9,2015

还可以选择使用<标志。它指示前面格式说明中的参数将被再次使用。也就是说,以下语句将产生与前面语句同样的输出结果:

image

警告:参数索引值从1开始,而不是从0开始,%1$...对第1个参数格式化。这就避免了与0标志混淆。

程序示例

image

运行结果

截止日期: 七月 3,2021
截止日期: 七月 3,2021

现在,我们已经了解了printf方法的所有特性。图(格式说明符)给出了格式说明符的语法图。

image

注释

数字和日期的格式化规则是特定于本地化环境的。例如,在德国,分组分隔符是点号而不是逗号,另外Monday被格式化为Montag。

文件输入与输出

读取文件

要想读取一个文件,需要构造一个Scanner对象,如下所示:

Scanner in =new Scanner(Path.of("myfile.txt"),StandardCharsets.UTF_8);

如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加一个额外的反斜杠转义:

"c:\\mydirectory\myfile.txt"

注释

在这里指定了UTF-8字符编码,这对于互联网上的文件很常见(不过并不是普遍适用)。读取一个文本文件时,要知道它的字符编码。如果省略字符编码,则会使用运行这个Java程序的机器的“默认编码”。这不是一个好主意,如果在不同的机器上运行这个程序,可能会有不同的表现。

现在,就可以利用前面介绍的任何一个Scanner方法对文件进行读取。

Printwriter对象

要想写入文件,就需要构造一个Printwriter对象。在构造器(constructor)中,需要提供文件名和字符编码:

PrintWriter out = new PrintWriter("myfile.txt",StandardCharsets.UTF_8);

如果文件不存在,创建该文件。可以像输出到System.out一样使用printprintln以及printf命令。

警告

可以构造一个带有字符串参数的Scanner,但这个Scanner会把字符串解释为数据,而不是文件名。例如,如果调用:

Scanner in = new Scanner("myfile.txt");    //ERROR?

这个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/myfile.txt"

正如读者所看到的,访问文件与使用System.inSystem.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.inSystem.out

java MyProg <myfile.txt> output.txt

这样,就不必担心处理IOException异常了。

标签:输出,Scanner,System,huangzihan,printf,println,输入,out
来源: https://www.cnblogs.com/Huang-zihan/p/15183236.html