【问题标题】:Java - Scanner declarationJava - 扫描仪声明
【发布时间】:2018-09-04 22:20:46
【问题描述】:

我是 Java 新手。 这是一个非常简单的切换方法。

当用户在这里键入 String 时,它会抛出一个错误,并且 catch 会按照编码再次调用此方法。

这是我关于扫描仪的问题。

我意识到我需要把那些

Scanner sc = new Scanner(System.in);

在“try”正文中,如果我想让它告诉我再次进行物理输入,但这是为什么呢?为什么要打字

int select = sc.nextInt();

还不够吗?

int select1 = sc.nextInt();

int select2 = sc.nextInt(); 是否相同,因为它具有相同的“sc”实例?

 public void reAsk(){
  System.out.println("Type a number")
  Scanner sc = new Scanner(System.in);

  try {
        int select = sc.nextInt();
        switch (select) {

        case 1:
            System.out.println("1");
            break;
        case 2:
            System.out.println("2");
            break;
        case 3:
            System.out.println("3");
            break;


    } catch (InputMismatchException e) {
        System.out.println("Please type int");
        reAsk();
    }
}

【问题讨论】:

  • 1.您必须将其放在try 块中,因为如果您输入的内容不是int,那么它将引发错误。在您的catch 块中,您可以调用该方法,以便只要输入无效,它本质上就会继续调用该方法
  • 2.不,他们不会是一样的。 nextInt() 函数消耗部分输入。因此,如果您只是输入 5 然后 6,第一次调用 nextInt() 将消耗 5,将其解析为第一个变量,然后第二次调用 nextInt() 将消耗 6 并将其解析为第二个变量,分别制作56这两个变量
  • 请不要再调用方法reAsk本身。这将增加方法嵌套,可能会减慢您的应用程序,因为另一个 reAsk 方法尚未完成但调用了另一个。相反,围绕你的逻辑包裹一个循环并重复循环,直到输入正常。

标签: java loops java.util.scanner


【解决方案1】:

调用nextInt()(或任何next() 方法)将简单地尝试读取流中的下一个标记(在nextInt() 的转换中,可能的符号(+/-)和数字),例如:标准输入。

如果您要输入:0 1 2,那么对nextInt() 的每次连续调用都将返回 0、1 和 2。

要继续Scanner,您不需要在每次调用reAsk 方法时创建Scanner,也不需要在这种微不足道的情况下使用递归(除非是为了练习): 你可以重复使用它,但你必须小心缓冲区中留下的字符,以防出错。

例如:

Scanner sc = new Scanner(System.in);
try {    
  ...
  int select;
  for (;;) {
    try {
      select = sc.nextInt();
      break;
    } catch (InputMismatchException ignored) {
      continue;
    }
  }
  // select is always initialized in that case
  switch (select) {
    ...
  }
}

这将执行无限循环,因为sc 无法读取int 并且缓冲区中仍然存在无效的int 字符(例如:'a 1')。

您可以使用sc.next() 前进(这将丢弃下一个令牌,例如:上例中的a)。

但在这种情况下使用sc.hasNextInt() 会更明智:

Scanner sc = new Scanner(System.in);
while (!sc.hasNextInt() && sc.hasNext()) {
  sc.next(); // advance / discard the invalid token
}

// we don't care about result of hasNext() here.
int select = sc.nextInt();

正如上面评论中所说,我们不测试 hasNext() 主要有两个原因:

  • 如果hasNext() 返回false,则流结束的可能性更大。您可能想在nextInt() 之前调用hasNextInt(),如果它返回false,请正确结束您的方法。此示例将失败并返回 NoSuchElementException
  • System.in 可能仅在它被重定向(例如:java Main < foobar.txtecho a | java Main)或调用某些序列(我不记得但我相信它是 Ctrl + Z)或关闭(in)时才会结束直接使用 Java (System.in.close())。

注意:在大多数情况下,Scanner 等资源是在 try-with-resources 中创建的,例如:

try (Scanner sc = new Scanner(System.in)) {
  ...
}

虽然这是一种很好的做法,但这会关闭System.in,您将永远无法使用它:

try (Scanner sc = new Scanner(System.in)) {
  String next = sc.next(); // again, without hasNext().
}
try (Scanner sc = new Scanner(System.in)) {
  String next = sc.next(); // fail NoSuchElementException (stream is closed).
}

在您的情况下,您可以忽略 try-with-resources

【讨论】:

    【解决方案2】:

    您的发现不正确。我已经修复了你的代码,希望这能解决你的问题:

    import java.util.InputMismatchException;
    import java.util.Scanner;
    
    public class Main {
    
        public static void reAsk() {
        System.out.println("Type a number");
        Scanner sc = new Scanner(System.in);
    
        try {
            int select = sc.nextInt();
            switch (select) {
    
            case 1:
                System.out.println("1");
                break;
            case 2:
                System.out.println("2");
                break;
            case 3:
                System.out.println("3");
                break;
    
            }
        } catch (InputMismatchException e) {
            reAsk();
        }
        }
    
        public static void main(String[] args) {
            reAsk();
        }
    
    }
    

    没有必要在 try catch 中初始化扫描器类。您只是有一些语法错误。首先,在 Java 中,每条语句都必须以分号结尾,您忽略了在 System.out.println("Type a number") 之后添加分号。

    【讨论】:

    • 你实际改变了什么?看起来你复制粘贴了他的代码并添加了一个 main 方法来调用函数,OP 不知道为什么他的代码不起作用......他在询问有关扫描仪的问题。
    • @AndrewG 他的代码有语法错误,我试图证明你不需要将扫描仪初始化移动到 try 代码中重复询问用户输入。
    • 您应该解释所有更改以及为什么需要更改。只贴代码对学习没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 2013-11-15
    • 2021-01-14
    • 2017-08-19
    • 1970-01-01
    • 2019-11-05
    • 2017-10-25
    相关资源
    最近更新 更多