在Java中从用户获取整数数组输入

3

我需要从用户那里获取一系列整数。用户不会被提示输入数字。输入将采用以下形式:

6

34 12 7 4 22 15

3

3 6 2

第一行表示第二行中整数的数量。 我最初尝试将第二行读取为字符串,并使用StringTokenizer在代码中将其分解为整数。由于这在我的程序中经常发生,所以耗时较长,我需要直接读取它们。 我记得在C++中它通常很简单。以下代码段可以解决问题。

for(i=0;i<6;i++)
cin>>a[i];

为了实现这个功能,我使用了java.util.Scanner工具,我的代码如下:
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
Scanner src = new Scanner(System.in);

for(x=0;x<2;x++){
    arraySize = Integer.parseInt(br.readLine());

    for(i=0;i<arraySize;i++)
        array[i] = src.nextInt();
}

在这种情况下,我遇到了以下错误:
Exception in thread "main" java.lang.NumberFormatException: For input string: "34 12 7 4 22 15"

我愿意听取建议,不仅局限在Scanner上。如果有其他方法可以实现这个目的,我也很乐意尝试。


我的猜测是arraySize = Integer.parseInt(br.readLine());会引发异常,我是对的吗? - ashutosh raina
3
分词器StringTokenizer很耗费时间吗?你进行过分析吗? - Raveline
这是作业吗?如果是,请添加“作业”标签... - home
在浏览并错过您已经尝试过它的提及后,我建议在我的答案中使用StringTokenizer。我也很好奇为什么您说StringTokenizer花了很长时间。它是运行时间长还是编程时间长?前者可能会暴露出您系统上的问题。而后者则会暴露出您实现设计上的问题。 - Mike Yockey
6个回答

12

供将来参考,以下是使用Scanner类的方法:

import java.util.Arrays;
import java.util.Scanner;


public class NumberReading {
    public static int [] readNumsFromCommandLine() {

        Scanner s = new Scanner(System.in);

        int count = s.nextInt();
        s.nextLine(); // throw away the newline.

        int [] numbers = new int[count];
        Scanner numScanner = new Scanner(s.nextLine());
        for (int i = 0; i < count; i++) {
            if (numScanner.hasNextInt()) {
                numbers[i] = numScanner.nextInt();
            } else {
                System.out.println("You didn't provide enough numbers");
                break;
            }
        }

        return numbers;
    }

    public static void main(String[] args) {
        int[] numbers = readNumsFromCommandLine();
        System.out.println(Arrays.toString(numbers));
    }
}

为什么需要第二个扫描仪? - user146303
为了清晰和基本验证,我想确保用户期望的数字都在第二行而不是分散在不同的行中。 - black panda

5

您说您可以使用以下C++代码:

for(i=0;i<6;i++) 
cin>>a[i];

如果在C++中您使用了这个,为什么不直接使用它呢?
for(i=0;i<6;i++)
a[i] = input.nextInt();

假设扫描仪声明如下:
Scanner input = new Scanner(System.in);

根据我所见,有些人试图为您编写整个程序。但是既然您表示可以使用C++代码解决此问题,那么我只是把这段代码转换成了Java。

如果您需要完整的代码,可以在此处找到:

import java.util.Scanner;

public class arrayFun {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        // Create a new array. The user enters the size
        int[] array = new int[input.nextInt()];

        // Get the value of each element in the array
        for(int i = 0; i < array.length; i++)
            array[i] = input.nextInt();

        /* Note that the user can type the following:
         * 6
         * 34 12 7 4 22 15
         * This will set the array to size 6
         * array[0] = 34;
         * array[1] = 12;
         * etc.
         */

    }

}

我知道这个回答有些晚了,但是当我搜索一个不同的问题时发现了这里。直到我意识到这不是我要找的东西,这里的答案让我很困惑。鉴于这仍然出现在谷歌上,我决定发布这个。


4
    Scanner in = new Scanner(inputFile);
    int[] ints = Arrays.stream(in.nextLine().split("\\s+"))
      .mapToInt(Integer::parseInt).toArray();

1
谢谢,伙计!我正在寻找一行代码。 - IndraP24

0
如果您的输入是由空格分隔的 "6 34 12 7 4 22 15 3 3 6 2",那么它将一次性被 br.readLine() 读取。您无法将 "6 34 12 7 4 22 15 3 3 6 2" 直接传递给 parseInt,正如您所见。
对于这种情况,我建议您在 br.readLine() 返回的字符串上调用 String.split(),然后您将得到一个字符串数组,可以依次传递给 Integer.parseInt()

我之前没有在问题中格式化我的输入。实际上,输入分为4行。我已经更新了上面的输入。 - Fawkes
在这种情况下,我会忽略count行并在实际数据所在的行上使用.split()方法。或者使用StringTokenizer。这里不太可能存在性能问题 - 如果有的话,你可以重新构建你的输入吗?当然要先进行分析。 - Matthew Gilliard
刚才重新阅读了问题 - 这是用户输入的数据?那么为什么要让他们有机会提供矛盾的信息,比如:"3" "1 2"? - Matthew Gilliard

0

这个很好用。事实上,这比StringTokenizer方法更快。感谢@yock。 - Fawkes

0
new Scanner(System.in).useDelimiter("[ ]") 

这应该有助于避免Vanathi在他的回答中提到的问题。至于知道数组的大小,可以使用类似以下的代码:

br.readLine().split("[ ]").length;

应该这样做。


该死,我的正则表达式太生疏了。只需要在括号之间放一个空格就可以很好地工作,但现在无法测试它。 - Raveline

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接