時間:2021/03/05
一.問題描述
今天在做OJ題時遇到使用nextLine方法讀取一整行輸入時為空字符串的情況,具體代碼如下:
Scanner in = new Scanner(System.in); HashMap<String, String> map = new HashMap<>(); int n = in.nextInt(); for(int i = 0; i < n; i++){ String str = in.nextLine(); String[] s = str.split(" "); map.put(s[0], str); }
按照提議是先讀取一個數字N表示輸入學生信息的個數,之后再讀取學生信息。
但是經過調試發現讀取的第一個str為空字符串,之后能夠正常讀取字符串。
二.問題原因
經過從網上查詢資料,了解到Scanner是一個掃描器,它掃描數據都是去內存中一塊緩沖區中進行掃描並讀入數據的,而我們在控制台中輸入的數據也都是被先存入緩沖區中等待掃描器的掃描讀取。這個掃描器在掃描過程中判斷停止的依據就是“空白符”,空格、回車等都算作是空白符。
上面代碼中的nextInt方法在掃描到有效字符后會將回車符留在緩沖區中,這就導致下面for循環中nextLine讀的第一個數據就是換行符,所以讀入的是空字符串。
next()與nextLine()的區別
- next()方法在讀取內容時,會過濾掉有效字符前面的無效字符,對輸入有效字符之前遇到的空格鍵、Tab鍵或Enter鍵等結束符,next()方法會自動將其過濾掉;只有在讀取到有效字符之后,next()方法才將其后的空格鍵、Tab鍵或Enter鍵等視為結束符;所以next()方法不能得到帶空格的字符串。
- nextLine()方法字面上有掃描一整行的意思,它的結束符只能是Enter鍵,即nextLine()方法返回的是Enter鍵之前沒有被讀取的所有字符,它是可以得到帶空格的字符串的。
- next()方法在掃描到空白符的時候會將前面的數據讀取走,但會丟下空白符“\r”在緩沖區中
- nextLine()方法在掃描的時候會將掃描到的空白符一同清理掉
三.問題解決
在nextInt方法下面加一個nextLine方法用來清理空白符。
修改后的代碼如下:
Scanner in = new Scanner(System.in); HashMap<String, String> map = new HashMap<>(); int n = in.nextInt(); String empty = in.nextLine(); //清理nextInt方法留下的空白符 for(int i = 0; i < n; i++){ String str = in.nextLine(); String[] s = str.split(" "); map.put(s[0], str); }