關(guān)于Scanner中nextInt()、nextLine()等方法總結(jié)與問題解決
Scanner.next?() 方法介紹
Scanner.next?() 有很多種方法,具體名稱與內(nèi)容可以見下表格:
關(guān)于Scanner.next?() 的輸入問題與分析
讓我們先來用代碼直觀地感受一下使用scanner時(shí)經(jīng)常出現(xiàn)的問題:
Scanner scanner = new Scanner(System.in); System.out.printf("請輸入你的名字: "); String name = scanner.nextLine(); System.out.printf("請輸入你的出生年份 : "); int age = scanner.nextInt(); System.out.printf("請輸入你喜歡的花 : "); String nan = scanner.nextLine(); System.out.printf( "你的名字是: " +name+ "%n 你的出生年份是 :" +age+ "%n 你喜歡的花是 :" +nan );
乍一看,沒有什么問題,就是三個(gè)簡單的輸入與讀取。但是讓我們來看看結(jié)果輸出:
請輸入你的名字: asd
請輸入你的出生年份 12
請輸入你喜歡的花 : 你的名字是: asd
你的出生年份是 :12
你喜歡的花是 :
Process finished with exit code 0
很明顯,最后一個(gè)在還沒有來得及輸入的情況下,直接執(zhí)行了輸出程序,然后結(jié)束了整個(gè)程序。
這是為什么呢?
這就涉及到上邊表格中提到的Scanner.next?()方法結(jié)束接收條件。我們在重復(fù)使用Scanner的時(shí)候,其實(shí)是在向同一個(gè)緩存區(qū)內(nèi)輸入數(shù)據(jù),而所謂結(jié)束接收條件其實(shí)就是不同的“斷句符號”。讓我們來快速地看一個(gè)例子與圖解加深一下理解。
Scanner scanner = new Scanner(System.in); String name = scanner.nextLine(); String age = scanner.nextLine(); String nan = scanner.nextLine(); System.out.printf( "name: " +name+ "%n age: " +age+ "%n nan: " +nan );
結(jié)果輸出:
12
23
21
name: 12
age: 23
nan: 21
Process finished with exit code 0
此時(shí)緩存區(qū)里內(nèi)容是:12\n23\n21\n 。而這三個(gè)數(shù)字為什么會(huì)被精準(zhǔn)的分配到變量name、age、nan中呢?就是因?yàn)閟canner.nextLine();函數(shù)的結(jié)束接收條件為\n。這個(gè)函數(shù)可以在接收到鍵盤輸出\n后停止接收,運(yùn)行下一個(gè)程序。而\n正是我們在日常程序中進(jìn)入下一個(gè)輸入時(shí)按的回車。
同理可得,上面那個(gè)程序如果正常輸入的話,緩存區(qū)里的內(nèi)容是:asd\n12\nCornflower\n 。那么問題出現(xiàn)了,在第二個(gè)程序中我們用的都是scanner.nextLine(); ,他會(huì)根據(jù)\n的位置完整地讀取每一份數(shù)據(jù)并賦值給對應(yīng)變量。而現(xiàn)在,我們用的分別是scanner.nextLine(); 、 scanner.nextInt(); 、 scanner.nextLine(); ,他們的結(jié)束接收條件分別為 \n 、數(shù)值、\n 。
此時(shí)三個(gè)函數(shù)就會(huì)將數(shù)據(jù)讀成這樣:
很明顯第二個(gè)scanner.nextInt()在遇到數(shù)值12后就已經(jīng)結(jié)束接收,而就在我按下“進(jìn)行下一個(gè)輸入”的回車時(shí),直接結(jié)束了第三個(gè) scanner.nextLine();的接收。
因此這就是為什么會(huì)出現(xiàn)后面的數(shù)據(jù)還沒有來得及輸入,程序就已經(jīng)結(jié)束的情況。
解決方法
那有沒有解決辦法呢?
肯定的好吧
方法很簡單,就是在第二個(gè)和第三個(gè)方法之間加簡單的 scanner.nextLine(); 方法 。這樣那個(gè)被錯(cuò)誤地結(jié)束第三個(gè)方法接收的“\n”,就被其他方法替代了。而第三個(gè)scanner.nextLine();也就可以正常接收數(shù)據(jù)了。
這是加上scanner.nextLine();后的緩存區(qū)讀取情況:
這是加上scanner.nextLine();后程序以及運(yùn)行結(jié)果:
Scanner scanner = new Scanner(System.in); System.out.printf("請輸入你的名字: "); String name = scanner.nextLine(); System.out.printf("請輸入你的出生年份 "); int age = scanner.nextInt(); scanner.nextLine(); //加的 System.out.printf("請輸入你喜歡的花 : "); String nan = scanner.nextLine(); System.out.printf( "你的名字是: " +name+ "%n 你的出生年份是 :" +age+ "%n 你喜歡的花是 :" +nan );
請輸入你的名字: asd
請輸入你的出生年份 12
請輸入你喜歡的花 : Cornflower
你的名字是: asd
你的出生年份是 :12
你喜歡的花是 :Cornflower
Process finished with exit code 0
這回就很愉快地輸入并輸出啦!
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot將mybatis升級為mybatis-plus的實(shí)現(xiàn)
之前項(xiàng)目工程用的是mybatis,現(xiàn)在需要將其替換為mybatis-plus,本文主要介紹了springboot將mybatis升級為mybatis-plus的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09基于spring@aspect注解的aop實(shí)現(xiàn)過程代碼實(shí)例
這篇文章主要介紹了基于spring@aspect注解的aop實(shí)現(xiàn)過程代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無法加載主類的問題
這篇文章主要介紹了解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無法加載主類的問題,具有很好的參考價(jià)值,對大家的學(xué)習(xí)或工作有一定的參考價(jià)值,需要的朋友可以參考下2023-09-09SpringBoot整合騰訊云COS對象存儲實(shí)現(xiàn)文件上傳的示例代碼
本文主要介紹了SpringBoot整合騰訊云COS對象存儲實(shí)現(xiàn)文件上傳的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12Java中關(guān)于Collections集合工具類的詳細(xì)介紹
Java提供了一個(gè)操作Set、List和Map等集合的工具類:Collections,該工具提供了大量方法對集合元素進(jìn)行排序、查詢和修改等操作,還提供了將集合對象設(shè)置為不可變、對集合對象實(shí)現(xiàn)同步控制等方法2021-09-09利用spring boot如何快速啟動(dòng)一個(gè)web項(xiàng)目詳解
這篇文章主要給大家介紹了關(guān)于利用spring boot如何快速啟動(dòng)一個(gè)web項(xiàng)目的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧、2017-12-12java(jdk)環(huán)境變量配置(XP、win7、win8)圖文教程詳解
對于初學(xué)java的同學(xué)來說,第一件事不是寫hello world,而是搭建好java開發(fā)環(huán)境,下載jdk,安裝,配置環(huán)境變量。這些操作在xp、win7、win8不同的操作系統(tǒng)里面配置不太一樣,下面通過本文給大家介紹如何在上面不同操作系統(tǒng)下配置2017-03-03