Java入門——輸入輸出

1.讀取輸入

通過(guò)調(diào)用System.out.println即可將輸出打印到“標(biāo)準(zhǔn)輸出流”(即控制臺(tái)窗口)。 從“標(biāo)準(zhǔn)輸入流” System.in中讀取并不是那么簡(jiǎn)單。 要讀取控制臺(tái)輸入,首先要構(gòu)造一個(gè)附加到System.in的 Scanner:

Scanner in = new Scanner(System.in);

現(xiàn)在,您可以使用Scanner類的各種方法來(lái)讀取輸入。 例如,nextLine方法讀取一行輸入。

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

在這里,我們使用nextLine方法,因?yàn)檩斎肟赡馨崭瘛?br> 要閱讀單個(gè)單詞(由空格分隔),用next方法

String firstName = in.next();

要讀取整數(shù),請(qǐng)使用nextInt方法

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

同樣,nextDouble方法讀取下一個(gè)浮點(diǎn)數(shù)。代碼清單3.2中的程序詢問(wèn)用戶的姓名和年齡,然后顯示如下消息:

Hello, Cay. Next year, you'll be 57

最后,注意這一行

import java.util.*;

在程序開始時(shí)。 Scanner類在java.util包中定義。 每當(dāng)使用基本java.lang包中未定義的類時(shí),都需要使用import指令。

Listing 3.2InputTest/InputTest.java 
1  import java.util.*; 
2  public class InputTest 
3  {
4     public static void main(String[] args)
5     {
6        Scanner in = new Scanner(System.in);
7 
8        // get first input
9        System.out.print("What is your name? ");
10        String name = in.nextLine();
11 
12        // get second input
13        System.out.print("How old are you? ");
14        int age = in.nextInt();
15 
16        // display output on console
17        System.out.println("Hello, " + name + ". Next year, you'll be " + (age + 1));
18     }
19 }

注意:The Scanner類不適合從控制臺(tái)讀取密碼,因?yàn)槿魏稳硕伎梢郧宄吹捷斎雰?nèi)容。 Java 6為此專門引入了一個(gè)Console類。 要讀取密碼,請(qǐng)使用以下代碼:

Console cons = System.console();
string userName= cons.readLine(“用戶名:”); 
char [] passwd = cons.readPassword(“ Password:”);

出于安全性考慮 原因是,密碼是以字符數(shù)組而不是字符串返回的。 處理完密碼后,應(yīng)立即使用填充值覆蓋數(shù)組元素。使用控制臺(tái)對(duì)象進(jìn)行輸入處理不如使用Scanner類進(jìn)行輸入處理方便。 您必須一次讀取輸入內(nèi)容, 沒(méi)有讀取單個(gè)單詞或數(shù)字的方法.

java.util.Scanner
?Scanner(InputStream in)
從給定的輸入流構(gòu)造一個(gè)Scanner對(duì)象。

?String nextLine()
讀取輸入的下一行。

?String next()
讀取輸入的下一個(gè)單詞(由空格分隔)。

?int nextInt()
?double nextDouble()
讀取并轉(zhuǎn)換表示整數(shù)或浮點(diǎn)數(shù)的下一個(gè)字符序列。

?boolean hasNext()
測(cè)試輸入中是否還有另一個(gè)單詞.

?boolean hasNextInt()
?boolean hasNextDouble()
測(cè)試下一個(gè)字符序列是整數(shù)還是浮點(diǎn)數(shù)。

java.lang.System
?static Console console()
返回一個(gè)Console對(duì)象,以便通過(guò)控制臺(tái)窗口與用戶進(jìn)行交互(如果可能的話),否則返回null。 控制臺(tái)對(duì)象可用于在控制臺(tái)窗口中啟動(dòng)的任何程序。 否則,可用性取決于系統(tǒng)。

java.io.Console
?static char [] readPassword((String prompt, Object... args)
?static String readLine((String prompt, Object... args)
顯示提示并讀取用戶 輸入,直到輸入行的末尾。args參數(shù)可用于提供格式參數(shù)。

2.格式化輸出

您可以使用語(yǔ)句System.out.print(x)在控制臺(tái)上打印一個(gè)數(shù)字x,該命令將以該類型的最大非零位數(shù)打印x。 例如,

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

輸出:

3333.3333333333335

如果要顯示美元和美分,這是一個(gè)問(wèn)題。在Java的早期版本中,格式化數(shù)字有點(diǎn)麻煩。 幸運(yùn)的是,Java 5從C庫(kù)中恢復(fù)了古老的printf方法。 例如,

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

打印x,其字段寬度為8個(gè)字符,精度為2個(gè)字符。 也就是說(shuō),打印輸出包含一個(gè)前導(dǎo)空格和七個(gè)字符。

3333.33

可以向printf提供多個(gè)參數(shù)。 例如:

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

每個(gè)以%字符開頭的格式說(shuō)明符都將替換為相應(yīng)的參數(shù)。 以格式說(shuō)明符結(jié)尾的轉(zhuǎn)換字符表示要格式化的值的類型:f是浮點(diǎn)數(shù),s是字符串,d是十進(jìn)制整數(shù)。 表3.5列出了所有轉(zhuǎn)換字符。


轉(zhuǎn)換符

另外,您可以指定控制格式化輸出外觀的標(biāo)志。 表3.6列出了所有標(biāo)志。 例如,逗號(hào)標(biāo)志添加了分組分隔符。

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

輸出

3,333.33

您可以使用多個(gè)標(biāo)志例如“%,(.2f”使用組分隔符并將負(fù)數(shù)括在括號(hào)中。


標(biāo)志

您可以使用靜態(tài)String.format方法創(chuàng)建帶格式的字符串,而無(wú)需打印它:

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

我們簡(jiǎn)要討論printf方法的日期和時(shí)間格式設(shè)置選項(xiàng)。 對(duì)于新代碼,應(yīng)使用java.time包的方法。 但是,您可以在舊版代碼中遇到Date類和相關(guān)的格式設(shè)置選項(xiàng)。格式由兩個(gè)字母組成,以t開頭,以表3.7的一個(gè)字母結(jié)尾。 例如,

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

以以下格式打印當(dāng)前日期和時(shí)間

Mon Feb 09 18:05:19 PST 2021
time轉(zhuǎn)換符
time轉(zhuǎn)換符

如表3.7所示,某些格式僅產(chǎn)生給定日期的一部分,例如,僅一天或一個(gè)月。 如果您必須多次提供日期來(lái)格式化每個(gè)部分,那將有點(diǎn)低效。 因此,格式字符串可以指示要格式化的參數(shù)的索引。 索引必須緊隨%之后,并且必須以$結(jié)尾。 例如,

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

或者,您可以使用<flag. 它指示應(yīng)再次使用與前面的格式規(guī)范中相同的參數(shù)。 就是說(shuō)

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

產(chǎn)生與前面的語(yǔ)句相同的輸出。

注意:參數(shù)索引值以1開頭,而不是以0:%1 $...格式化第一個(gè)參數(shù)。 這避免了與0標(biāo)志的混淆.

現(xiàn)在,您已經(jīng)看到了printf方法的所有功能。 圖3.6顯示了格式說(shuō)明符的語(yǔ)法圖


格式說(shuō)明符

3.文件輸入輸出

要從文件中讀取,請(qǐng)構(gòu)造一個(gè)Scanner對(duì)象,如下所示:

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

如果文件名包含反斜杠,請(qǐng)記住使用一個(gè)附加的反斜杠對(duì)每個(gè)轉(zhuǎn)義符進(jìn)行轉(zhuǎn)義:“ c:\\ mydirectory \\ myfile.txt”

注意:在此,我們指定UTF-8字符編碼,這對(duì)于Internet上的文件是通用的(但不是通用的)。 閱讀文本文件時(shí),您需要知道字符編碼( 如果省略字符編碼,則使用運(yùn)行Java程序的計(jì)算機(jī)的“默認(rèn)編碼”。 這不是一個(gè)好主意-程序可能會(huì)在不同的地方運(yùn)行,因此其運(yùn)行可能有所不同。

現(xiàn)在,您可以使用已經(jīng)介紹過(guò)的任何Scanner方法從文件中讀取文件。要寫入文件,請(qǐng)構(gòu)造一個(gè)PrintWriter對(duì)象。 在構(gòu)造函數(shù)中,提供文件名和字符編碼:

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

如果該文件不存在,則會(huì)創(chuàng)建它。 您可以像打印到System.out時(shí)一樣使用print,println和printf命令。

注意:可以使用字符串參數(shù)構(gòu)造Scanner,但是掃描程序會(huì)將字符串解釋為數(shù)據(jù),而不是文件名。 例如,如果在
Scanner in = new Scanner(“ myfile.txt”)// error?
中調(diào)用Scanner; 然后,掃描程序?qū)⒖吹绞畟€(gè)字符的數(shù)據(jù):'m','y','f',依此類推。

注:當(dāng)您指定相對(duì)文件名時(shí),例如“ myfile.txt”,“ mydirectory / myfile.txt”或“ ../myfile.txt”,該文件相對(duì)于Java所在的目錄 虛擬機(jī)已啟動(dòng)。 如果從命令外殼啟動(dòng)程序,則通過(guò)執(zhí)行

java MyProg

起始目錄是命令外殼的當(dāng)前目錄。 但是,如果使用集成開發(fā)環(huán)境,它將控制開始目錄。 您可以通過(guò)以下調(diào)用找到目錄位置:

String dir = System.getProperty(“ user.dir”);

如果在查找文件時(shí)遇到麻煩,請(qǐng)考慮使用絕對(duì)路徑名,例如

“ c:\\ mydirectory \\ myfile.txt”

”/home/me/mydirectory/myfile.txt”。

如您所見(jiàn),您可以像使用System.in和System.out一樣輕松地訪問(wèn)文件。 有一個(gè)問(wèn)題:如果使用不存在的文件構(gòu)造Scanner或使用無(wú)法創(chuàng)建的文件名構(gòu)造PrintWriter,則會(huì)發(fā)生異常。 例如,Java編譯器認(rèn)為這些異常比“除以0”異常更為嚴(yán)重。 您可以通過(guò)使用throws子句標(biāo)記main方法來(lái)做到這一點(diǎn),如下所示:

public static void main(String[] args) throws IOException
{   
Scanner in = new Scanner(Path.of("myfile.txt"), StandardCharsets.UTF_8);  
 . . .
}

注意:從命令外殼啟動(dòng)程序時(shí),可以使用外殼的定向語(yǔ)法并將任何文件附加到System.in和System.out:
java MyProg <myfile.txt> output.txt
然后,您無(wú)需擔(dān)心處理IOException的問(wèn)題。

java.util.Scanner
?Scanner(Path p, String encoding)
構(gòu)造一個(gè)使用給定字符編碼從給定路徑讀取數(shù)據(jù)的掃描器。

?Scanner(String data)
構(gòu)造一個(gè)從給定的string讀取數(shù)據(jù)的掃描器。

java.io.PrintWriter
?PrintWriter(String fileName)構(gòu)造一個(gè)PrintWriter,該P(yáng)rintWriter將數(shù)據(jù)寫入具有給定文件名的文件中。

java.nio.file.Path
?static Path of(String pathname)
根據(jù)給定的路徑名構(gòu)造路徑

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容