【问题标题】:Alternative way to get the string input from the user [duplicate]从用户获取字符串输入的替代方法[重复]
【发布时间】:2021-02-14 15:01:38
【问题描述】:

我已经实现了以下将这些值作为输入的代码:-

3 6
CLICK 1
CLICK 2
CLICK 3
CLICK 2
CLOSEALL
CLICK 1

但是为了接受字符串输入,我尝试了 nextLine() 但在这种情况下它没有接受输入。如果我使用 next() 那么它将 CLICK1 视为两个不同的字符串,所以我得到 @987654324 @ 因为我正在拆分字符串并将其解析为 int。处理此类输入的替代方法是什么?

import java.util.*;
    
public class TweetClose {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int open = 0;
        int a[] = new int[50];

        for (int i = 1; i <= n; i++) {
            a[i] = 0;
        }

        for (int i = 0; i < k; i++) {
            String s = sc.nextLine();
            if (s.equals("CLOSEALL")) {
                open = 0;
                for (int j = 1; j <= n; j++) {
                    a[j] = 0;
                }
            } else {
                String[] st = s.split(" ");
                int y = Integer.parseInt(st[1]);
                if (a[y] != 1) {
                    a[y] = 1;
                    open++;
                }
            }
            System.out.println(open);
        }
        sc.close();
    }
}

【问题讨论】:

  • 除了在sc.nextInt() 之后使用sc.nextLine() 的问题之外,ArrayIndexOutOfBoundsException 还有其他可能的原因,其中数组a 是使用固定大小创建的,然后从未经验证的用户索引应用输入:for (int i = 1; i &lt;= n; i++)for (int j = 1; j &lt;= n; j++) - 如果n &gt;= 50; CLICK 后解析数字时的类似问题:int y = Integer.parseInt(st[1]); if (a[y] != 1): if y&gt;=50

标签: java arrays string


【解决方案1】:

sc.nextInt() 不扫描回车符。您需要确保在尝试解析下一个输入之前对其进行扫描。

例如:

import java.util.*;

public class TweetClose {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.nextLine();
        int k = sc.nextInt();
        sc.nextLine();
        int open = 0;
        int[] a = new int[50];
        for (int i = 1; i <= n; i++) {
            a[i] = 0;
        }
        for (int i = 0; i < k; i++) {
            String s = sc.nextLine();
            if (s.equals("CLOSEALL")) {
                open = 0;
                for (int j = 1; j <= n; j++) {
                    a[j] = 0;
                }
            } else {
                String[] st = s.split(" ");
                int y = Integer.parseInt(st[1]);
                if (a[y] != 1) {
                    a[y] = 1;
                    open++;
                }
            }
            System.out.println(open);
        }
        sc.close();
    }
}

【讨论】:

  • 这仅在每一行仅包含一个标记时才有效。但是输入的每行都有 1-2 个标记。
  • 谢谢@Domenico Siblio 它解决了我的问题。
  • 我回答时问题的格式不正确,因此无法知道 36 是否真的输入在同一行或 2 个不同的行上。我的印象是所有令牌都在一行中传递,如果不是这种情况,那么删除nk 声明之间的额外sc.nextLine() 很简单。感谢您的关注。
  • @SiaSaxena,没问题!由于您是该网站的新手,我建议您将我的答案标记为已接受以关闭该线程。祝你有美好的一天。
【解决方案2】:

使用nextLine()引起的问题。您应该改用next(),因为您要处理下一个令牌。

处理完所有标记后,当前行的最后一个换行符仍在内存中。 nextLine() 返回该换行符“\n”。然后你处理它:

String[] st = s.split(" ");
int y = Integer.parseInt(st[1]);

split 函数返回一个只有一个元素(“\n”)的数组,因此您无法解析 st[1]。没有这样的元素,只有st[0]存在。

它将使用 next() 而不是 nextLine() 因为 next() 跳过换行符并继续下一行的下一个标记。

这是一个很常见的错误,因为没有 nextString() 函数。

【讨论】:

  • 但是使用 next() 我们不能使用带空格的字符串
  • 是的,但是您可以执行sc.next(),如果它返回"CLICK",您可以调用sc.nextInt() 来检索号码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 2012-05-10
  • 2014-10-02
相关资源
最近更新 更多