Системный ввод в Java не работает правильно

Я пытаюсь создать программу, которая принимает Ints и дает мне сумму, и я хочу сделать это с помощью регулярных выражений. Ввод содержит цифры, символы и буквы. Например, когда я пишу: java GiveMeSum 4 2 1 -5 или java GiveMeSum 4k "2 1!-5 программа должна написать 2 Но это не только дает мне неправильный ответ, но и не читает все мои входные данные. Когда я пишу:

java GiveMeSum 4 2 1 -5

4 5 4 5 4 5 4 5

Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at GiveMeSum.main(GiveMeSum.java:12)


public class GiveMeSum {

public static void main(String[] args) throws IOException {
    int sum = 0;
    Scanner sc = new Scanner(System.in).useDelimiter("(\\D|^-)");
    for ( int i = 0; i < args.length; i++) {
        sum += sc.nextInt();
    }
    System.out.println(sum);
}

}

И не было этого исключения. Это просто обнаружилось внезапно

3 ответа

Решение

Это происходит потому, что вы передаете "4 2 1 -5" не как входные данные, а как аргументы, чтобы они args параметр main метод. Чтобы передать их в качестве ввода, дождитесь запуска приложения и введите их или используйте перенаправление потока ввода

Обновление (код для обработки аргументов)

Как я должен написать это в Java, чтобы принять ввод в качестве аргументов тогда? Есть ли конкретный простой способ?

Я бы сказал, что использование аргументов для нефиксированного числа входных параметров не очень хорошая идея. Я бы все еще сказал, что использование входного потока - это путь, для которого он и был разработан! Кроме того, ваши требования разбора немного неясны. Все еще здесь моя попытка

public class Main
{
    static OptionalInt parseOnlyInt(String s)
    {
        String digitsOnly = s.replaceAll("[^0-9]", "");
        if (digitsOnly.length() == 0)
            return OptionalInt.empty();
        else
            return OptionalInt.of(Integer.parseInt(digitsOnly));
    }

    public static void main(String[] args)
    {
        int sum = Arrays.stream(args)
                .map(Main::parseOnlyInt)
                // probably in Java 9 OptionalInt::stream would be better than next 2 lines
                // see https://bugs.openjdk.java.net/browse/JDK-8050820
                .filter(OptionalInt::isPresent)
                .mapToInt(OptionalInt::getAsInt)
                .sum(); 

        System.out.println(Arrays.toString(args));
        System.out.println(sum);    
    }
}

Или, если вы предпочитаете старый (не Java-8) способ здесь

public static void main(String[] args)
{
    int sum = 0;
    for (int i = 0; i < args.length; i++)
    {
        String digitsOnly = args[i].replaceAll("[^0-9]", "");
        if (digitsOnly.length() != 0)
            sum += Integer.parseInt(digitsOnly);
    }
    System.out.println(Arrays.toString(args));
    System.out.println(sum);
}

System.in - это входной поток. Он получает данные только после запуска вашей программы. Попробуйте посмотреть на параметр args в main. Вот где данные помещаются, когда они передаются во время вызова.

Простое решение oneliner, чтобы взять аргументы и вывести сумму

public static void main(String[] args) {
    int sum = Arrays.stream(args) // Create a stream from the array
            .mapToInt(Integer::parseInt) // Parse the strings as integers
            .sum(); // Sum
    System.out.println(sum);
}
Другие вопросы по тегам