为什么我必须使用in.nextLine();两次?

时间:2016-01-11 22:11:07

标签: java string

所以在我的计算机科学课上,我经常在截止日期前完成作业。在我的空闲时间,我正在创建一个基本的文本RPG来娱乐自己。当我尝试使用代码response = in.nextLine();时,我遇到的一个问题是我必须使用该行代码两次才能获得所需的结果。

这是我程序中的方法。

public void room1(){
    System.out.println("The room you are in is empty, I'm not sure how you got in here, I don't write stories. There is one exit to the North. What do you do?");
    System.out.print(">");
    response = in.nextLine();
    response = in.nextLine();
    response = response.toLowerCase();
    if(response.indexOf("go north")>=0){
        move();
        move();
        move();
        room2();
    }

}

你可以看到我有两行重复代码,但为了让我真正给出一个像" Go North"第二行代码必须在那里。为什么会这样,我怎么能这样做,所以我不必重复代码行?

P.S。 move();是因为我使用Karel J Robot作为游戏的玩家和地图。

3 个答案:

答案 0 :(得分:0)

您发布的代码本身不包含任何问题。我怀疑你正在读取其他地方的东西(例如整数),这会在输入中留下换行符。因此,当您调用此方法时,第一个nextLine()调用将使用该换行符。因此,它似乎跳过一个输入(或要求您进行两次nextLine()次呼叫)。

考虑这个例子:

import java.util.Scanner;

public class temp
{
    public static Scanner in = new Scanner(System.in);

    public static void main(String[] args)
    {
       while (true) {
          System.out.print("Number:");
          int n = in.nextInt();
          System.out.print("Line1:");
          String r1 = in.nextLine();
          System.out.print("Line2:");
          String r2 = in.nextLine();
          System.out.println("Done "+r1);
          System.out.println("Done "+r2);
       }
    }
}

这将始终跳过“Line1”输入。你可能有完全相同的问题。你可以通过调用nextLine()来修复它,你可能会留下一个尾随的换行符。

答案 1 :(得分:0)

问题可能是I3x所说的(代码中的其他地方在输入中留下了一个新行)因为我试图重现代码并且它按预期工作。你可以测试它,也许它会帮助你。

public class Main {

    public static void main(String[] args) {
        room1();
    }

    public static void room1() {
        System.out.println("The room you are in is empty, I'm not sure how you got in here, I don't write stories. There is one exit to the North. What do you do?");
        System.out.print(">");
        Scanner in = new Scanner(System.in);
        String response = in.nextLine();
        response = response.toLowerCase();

        if (response.indexOf("go north") >= 0) {
            System.out.println(response);
        }
    }
}

答案 2 :(得分:0)

答案很简单:java.util.Scanner的内部解析器方法(如nextInt()nextDouble()next()不会读取解析换行符。

举例来说,以下输入......

5 4
three

开始时,在您完全使用扫描仪之前,光标位于...

|5 4
three

...在5.之前。假设您拨打in.nextInt() ...

5| 4
three

看那个!光标在5 之后立即停止,因为它已经完成了读取整数的位置。让我们再次致电in.nextInt() ......

5 4|
three

现在它位于4 之后的。请注意,它不在3之前......这是一个巨大的差异。因为它现在的位置和后面的快照描绘的区别......

5 4
|three

......太棒了。这两个光标点之间有一个换行符。现在这就是你看似神秘的问题所解决的......在你的情况下,你可能会遇到这种竞争条件,你在使用nextLine()之前使用了Scanner的一种解析输入方法,并在某处留下了潜在的换行符,在消耗实际输入之前,您第一次调用in.nextLine()消耗的内容。

所以,如果我们回到这个状态......

5 4|
three

致电in.nextLine()会将我们带到......

5 4
|three

(它消耗了所有内容,包括换行符,就像在缓冲区中一样......在这种情况下导致""空字符串。)

再次致电in.nextLine()会带给我们......

5 4
three
|

注意光标不在三个末尾,而是在下一行,因为它消耗了前一行的所有内容,包括存在的换行符,这导致字符串{{1 }}

我喜欢在白天玩这个回来:)。事实上,C ++的"three"int five, four; cin >> five >> four;表现得非常相似:),你需要一个额外的string three; getline(cin, three);来摆脱那个讨厌的尾随换行符:)