You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java猜词游戏首次循环后异常:二次输入'n'时出错求助

解决猜词游戏第二次游玩输入'n'报错的问题

嘿,我看到你这个猜词游戏遇到的问题了——第二次游玩时输入'n'会触发错误,对吧?让我帮你拆解一下问题根源,然后给出修复方案。

问题根源分析

你的错误本质上是输入流缓冲区残留的换行符引发的连锁反应,具体过程是这样的:

  1. 第一次游戏结束后,你用input.next()获取用户是否重玩的选择,这个方法只会读取用户输入的字符(比如Y/N),但不会读取用户按下的回车键(换行符),这个换行符会留在输入缓冲区里。
  2. 进入第二次游戏循环后,第一个letterGuess = input.nextLine()会直接读取到这个残留的换行符,也就是空字符串""。
  3. Java里SECRET_WORD.indexOf("")会返回0(空字符串默认匹配任何字符串的开头),于是代码会把wordSoFar从"-----"改成"----"(长度从5变成4)。
  4. 当你输入'n'(转成大写为"N"),SECRET_WORD.indexOf("N")返回4(因为"BRAIN"的最后一个字母N在索引4的位置),接下来代码尝试执行wordSoFar.substring(5,4)——起始索引大于结束索引,直接抛出StringIndexOutOfBoundsException,这就是你遇到的错误。

修复方案

1. 清空输入缓冲区的残留换行符

在使用input.next()获取重玩选择后,添加一行代码清空缓冲区里的换行符:

System.out.println("Would you like to play again?");
repeat = input.next();
input.nextLine(); // 新增这行,清空残留的换行符

2. 拦截空输入的情况

在处理用户输入的字母之前,先判断是否为空,如果是空输入,提示用户重新输入,避免后续的索引操作出错:
在letterGuess = letterGuess.toUpperCase()之后添加:

// 处理空输入,要求用户输入有效内容
while (letterGuess.isEmpty()) {
    System.out.print("Please enter a valid letter or " + FLAG + ": ");
    letterGuess = input.nextLine().toUpperCase();
}

3. 优化错误计数逻辑(额外小修复)

当前代码里,当用户输入!(猜整个单词的标记)时,会被当成错误字母计数,这显然不合理。我们可以调整逻辑,先判断是否是标记,再处理字母猜测:

System.out.print("Enter a letter (" + FLAG + " to guess entire word): ");
letterGuess = input.nextLine();
letterGuess = letterGuess.toUpperCase();

// 先处理空输入
while (letterGuess.isEmpty()) {
    System.out.print("Please enter a valid letter or " + FLAG + ": ");
    letterGuess = input.nextLine().toUpperCase();
}

// 如果是猜整个单词的标记,直接跳出循环处理,不计数错误
if (letterGuess.equals(FLAG)) {
    break;
}

// 处理字母猜测的逻辑
if (SECRET_WORD.indexOf(letterGuess) >= 0) {
    // 注意:当前代码只替换第一个匹配的字母,如果秘密单词有重复字母(比如"APPLE"),需要后续优化遍历替换所有匹配项
    updatedWord = wordSoFar.substring(0, SECRET_WORD.indexOf(letterGuess));
    updatedWord += letterGuess;
    updatedWord += wordSoFar.substring(SECRET_WORD.indexOf(letterGuess)+1, wordSoFar.length());
    wordSoFar = updatedWord;
} else {
    numGuesses += 1;
}

修复后的完整代码

/* * WordGuess.java */
import java.util.Scanner;
/**
 * Plays a word guessing game with one player.
 * */
public class WordGuess {
 //Main method
 public static void main(String[] arqs) {
 final String SECRET_WORD = "BRAIN";
 final String FLAG = "!";
 String wordSoFar = "", updatedWord = "";
 String letterGuess, wordGuess = "";
 int numGuesses = 0;
 String repeat = "";
 Scanner input = new Scanner(System.in);
 /* begin game */
 System.out.println ( "Word Guess game. \n" );
 do{
 numGuesses = 0;
 wordSoFar = "";
 updatedWord = "";
 for (int i = 0; i < SECRET_WORD.length() ; i++) {
 wordSoFar += "-"; //word, as dashes
 }
 System.out.println("Your word is ");
 System.out.println(wordSoFar + "\n"); //displays dashes
 /* allow player to make guesses */
 do{
 System.out.print("Enter a letter (" + FLAG + " to guess entire word): ");
 letterGuess = input.nextLine();
 letterGuess = letterGuess.toUpperCase() ;

 // 处理空输入,要求用户输入有效内容
 while (letterGuess.isEmpty()) {
     System.out.print("Please enter a valid letter or " + FLAG + ": ");
     letterGuess = input.nextLine().toUpperCase();
 }

 // 如果是猜整个单词的标记,直接跳出循环处理,不计数错误
 if (letterGuess.equals(FLAG)) {
     break;
 }

 /* player correctly guessed a letter--extract string in wordSoFar
 * up to the letter guessed and then append guessed letter to that
 * string Next, extract rest of wordSoFar and append after the guessed
 * letter */
 if (SECRET_WORD.indexOf(letterGuess) >= 0) {
 updatedWord = wordSoFar.substring(0, SECRET_WORD.indexOf(letterGuess));
 updatedWord += letterGuess;
 updatedWord += wordSoFar.substring(SECRET_WORD.indexOf(letterGuess)+1, wordSoFar.length() ) ;
 wordSoFar = updatedWord;
 }else {
 numGuesses += 1;
 }
 /* display guessed letter instead of dash */
 System.out.println(wordSoFar + "\n");
 } while (!wordSoFar.equals(SECRET_WORD) && numGuesses < 6);
 /* finish game and display message and number of guesses */
 if (letterGuess.equals(FLAG)) {
 System.out.println("What is your guess? ");
 wordGuess = input.nextLine() ;
 wordGuess = wordGuess.toUpperCase() ;
 }
 if (wordGuess.equals(SECRET_WORD) || wordSoFar.equals(SECRET_WORD)) {
 System.out.println ( "You won! " ) ;
 } else {
 System.out.println("Sorry. You lose.");
 }
 System.out.println("The secret word is " + SECRET_WORD);
 System.out.println("You made " + numGuesses + " mistake.");
 System.out.println("Would you like to play again?");
 repeat = input.next();
 input.nextLine(); // 清空残留的换行符
 }while(repeat.equalsIgnoreCase("Y"));
 System.out.println("GOOD BYE THANKS FOR PLAYING!");
 }
}//end of Word Guess class

后续优化提示

等你解决完这个问题后,替换成随机单词数组的计划就可以正常推进了。另外,当前代码只能替换单词中第一个匹配的字母,如果之后要支持有重复字母的秘密单词,你可以遍历整个字符串,把所有匹配的位置都替换成猜测的字母。

内容的提问来源于stack exchange,提问作者ARYA 8B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 11:02:31