как вводить несколько строк одновременно в java? [Дубликат]

AngularJS 2.0 также может работать на сервере. Vojta Jina рассказывает об этом на шоу «JavaScript Jabber» # 109 - http://javascriptjabber.com/109-jsj-dependency-injection-in-javascript-with-vojta-jina-misko-hevery/ (32:30 в плейере). Существует ссылка на новый модуль инъекции AngularJS ' https://github.com/angular/di.js .

490
задан Lii 4 April 2018 в 13:31
поделиться

15 ответов

Это потому, что метод Scanner.nextInt не использует символ последней новой строки вашего ввода и, следовательно, newline потребляется в следующий вызов Scanner.nextLine .

Вы столкнетесь с аналогичным поведением, когда вы используете Scanner.nextLine после Scanner.next() или любого метода Scanner.nextFoo (кроме самого nextLine).

Обход проблемы:

  • Пропустить пустой Scanner.nextLine вызов после Scanner.nextInt или Scanner.nextFoo, чтобы потреблять остальную часть этой линии, включая newline
    int option = input.nextInt();
    input.nextLine();  // Consume newline left-over
    String str1 = input.nextLine();
    
  • Или было бы еще лучше, если вы прочитаете ввод через Scanner.nextLine и преобразуете свой ввод в нужный формат. Например, к целому числу с использованием метода Integer.parseInt(String) .
    int option = 0;
    try {
        option = Integer.parseInt(input.nextLine());
    } catch (NumberFormatException e) {
        e.printStackTrace();
    }
    String str1 = input.nextLine();
    
582
ответ дан cricket_007 15 August 2018 в 14:43
поделиться
  • 1
    @blekione. Тогда, вероятно, оставим это пока. Они используются для обработки исключений, которые вы узнаете позже. На данный момент используйте первый подход. – Rohit Jain 27 October 2012 в 17:54
  • 2
    Могу ли я использовать только option = Integer.parseInt(input.nextLine());} вместо полного try{...}? Есть ли недостаток в использовании только выше? – blekione 27 October 2012 в 18:52
  • 3
    @blekione. Вы должны использовать try-catch, потому что Integer.parseInt выбрасывает NumberFormatException, когда ему передается недопустимый аргумент. Вы узнаете об исключении позже. Для E.G: - Integer.parseInt("abc"). Вы не хотите & quot; abc & quot; чтобы преобразовать в int правильно? – Rohit Jain 27 October 2012 в 19:02
  • 4
    @blekione. Итак, в приведенном выше случае ваш код будет остановлен в этот момент, и вы не сможете продолжить выполнение. С обработкой исключений вы можете справиться с такими условиями. – Rohit Jain 27 October 2012 в 19:02
  • 5
    В какой степени это лучше? AFAIK Scanner # nextInt () является более мягким в поиске правильных ints, разрешая групповые запятые и языковые префиксы и суффиксы. Integer # parseInt () позволяет использовать только цифры и десятичную точку плюс дополнительный знак. – Mordechai 11 January 2017 в 04:00

Если вы хотите прочитать обе строки и ints, решение должно использовать два сканера:

Scanner stringScanner = new Scanner(System.in);
Scanner intScanner = new Scanner(System.in);

intScanner.nextInt();
String s = stringScanner.nextLine(); // unaffected by previous nextInt()
System.out.println(s);

intScanner.close();
stringScanner.close();
2
ответ дан André Valenti 15 August 2018 в 14:43
поделиться

Вместо input.nextLine() используйте input.next(), что должно решить проблему.

Измененный код:

public static Scanner input = new Scanner(System.in);

public static void main(String[] args)
{
    System.out.print("Insert a number: ");
    int number = input.nextInt();
    System.out.print("Text1: ");
    String text1 = input.next();
    System.out.print("Text2: ");
    String text2 = input.next();
}
4
ответ дан arghtype 15 August 2018 в 14:43
поделиться

sc.nextLine() лучше по сравнению с анализом ввода. Потому что производительность разумна, это будет хорошо.

1
ответ дан Aurasphere 15 August 2018 в 14:43
поделиться

Это потому, что, когда вы вводите номер, нажмите «Ввод», input.nextInt() потребляет только номер, а не «конец строки». Когда input.nextLine() выполняется, он потребляет «конец строки» все еще в буфере с первого входа.

Вместо этого используйте input.nextLine() сразу после input.nextInt()

62
ответ дан Bohemian 15 August 2018 в 14:43
поделиться
  • 1
    Ммм, эта ошибка была исправлена ​​через несколько дней? – Victor 29 May 2014 в 14:28
  • 2
    @Victor это не ошибка. он работает как указано. вы можете утверждать, что должен быть простой способ сказать api также использовать любые пробелы после целевого ввода. – Bohemian♦ 29 May 2014 в 14:38
  • 3
    Понимаю. спасибо @Bohemian, что именно то, что я спорю. Я думаю, что это должно быть изменено, возможно, вы можете указать мне, где предложить эту «проблему». в следующем JCP. – Victor 29 May 2014 в 15:55
  • 4
    @victor Вы можете запросить (и узнать, как внести код) в функцию с помощью страницы Сообщить об ошибке или запросить функцию . – Bohemian♦ 29 May 2014 в 16:18
  • 5

Кажется, есть много вопросов об этой проблеме с java.util.Scanner. Я думаю, что более читаемым / идиоматическим решением было бы вызвать scanner.skip("[\r\n]+"), чтобы удалить любые символы новой строки после вызова nextInt().

ИЗМЕНИТЬ: как показано ниже, как @PatrickParker, это вызовет бесконечный цикл, если пользовательские входы любые пробелы после номера. См. Их ответ на лучший шаблон для использования с пропуском: https://stackoverflow.com/a/42471816/143585

33
ответ дан Community 15 August 2018 в 14:43
поделиться

Проблема заключается в методе input.nextInt () - он только считывает значение int. Поэтому, когда вы продолжаете чтение с помощью input.nextLine (), вы получаете ключ «\n» Enter. Поэтому, чтобы пропустить это, вы должны добавить input.nextLine (). Надеюсь, это должно быть ясно сейчас.

Попробуйте это так:

System.out.print("Insert a number: ");
int number = input.nextInt();
input.nextLine(); // This line you have to add (It consumes the \n character)
System.out.print("Text1: ");
String text1 = input.nextLine();
System.out.print("Text2: ");
String text2 = input.nextLine();
168
ответ дан Ebony Maw 15 August 2018 в 14:43
поделиться

Что вам нужно знать:

    текст, который представляет несколько строк, также содержит непечатаемые символы между строками (мы называем их разделителями строк), как возврат каретки (CR - в строковых литералах, представленных как "\r") line line (LF - в строковых литералах, представленных как "\n")
  • , когда вы читаете данные с консоли, это позволяет пользователю вводить свой ответ, и когда он будет сделан, ему необходимо как-то подтверждают этот факт. Для этого пользователю необходимо нажать клавишу «enter» / «return» на клавиатуре. Важно то, что этот ключ, помимо обеспечения помещения пользовательских данных в стандартный вход (представленный System.in, который читается Scanner), также отправляет зависимые от ОС разделители строк (например, для Windows \r\n) после этого. Поэтому, когда вы запрашиваете у пользователя значение типа age, а пользовательские типы 42 и нажатия вводятся, стандартный ввод будет содержать "42\r\n".

Проблема

Scanner#nextInt (и другие методы Scanner#nextType) не позволяют сканеру потреблять эти разделители строк. Он прочитает их из System.in (как еще Сканер знал бы, что больше нет цифр от пользователя, которые представляют age значение, чем перед пробелом?), Который удалит их со стандартного ввода, но он также будет кешем эти разделители строк внутри. Нам нужно помнить, что все методы Scanner всегда сканируются, начиная с кэшированного текста.

Теперь Scanner#nextLine() просто собирает и возвращает все символы , пока не найдет разделители строк (или конец потока). Но поскольку разделители строк после прочтения номера из консоли сразу обнаруживаются в кеше сканера, он возвращает пустую строку, что означает, что сканер не смог найти символ до этих разделителей строк (или конца потока). BTW nextLine также потребляет эти разделители строк.

Решение

Поэтому, когда вы хотите запросить номер, а затем для всей строки и избежать этой пустой строки в результате nextLine, либо

  • после nextInt поместить дополнительный nextLine вызов, чтобы использовать разделители строк из кеша сканеров,
  • не использовать nextInt (ни next, ни любое nextTYPE ] методов). Вместо этого прочитайте целые строки данных по строке nextLine и номера разбора из каждой строки (при условии, что одна строка содержит только одно число) для правильного типа, например int через Integer.parseInt.

BTW: Scanner#nextType методы могут пропускать разделители (по умолчанию все пробелы, такие как вкладки, разделители строк), в том числе кэшированные сканером, пока они не найдут следующее значение без разделителя (токен). Благодаря этому для ввода типа "42\r\n\r\n321\r\n\r\n\r\nfoobar" код

int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();

сможет правильно назначить num1=42 num2=321 name=foobar.

15
ответ дан eFarzad 15 August 2018 в 14:43
поделиться

Он делает это, потому что input.nextInt(); не фиксирует новую строку. вы могли бы сделать, как и другие, добавив под ним input.nextLine();. В качестве альтернативы вы можете сделать это в стиле C # и разобрать nextLine на целое число так:

int number = Integer.parseInt(input.nextLine()); 

Выполнение этого работает так же хорошо, и оно сохраняет строку кода.

23
ответ дан Electric Coffee 15 August 2018 в 14:43
поделиться
public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int i = scan.nextInt();
        scan.nextLine();
        double d = scan.nextDouble();
        scan.nextLine();
        String s = scan.nextLine();

        System.out.println("String: " + s);
        System.out.println("Double: " + d);
        System.out.println("Int: " + i);
    }
0
ответ дан Neeraj Gahlawat 15 August 2018 в 14:43
поделиться
  • 1
    Если вы используете метод nextLine () сразу после метода nextInt (), напомните, что nextInt () читает целые числа; из-за этого последний символ новой строки для этой строки целочисленного ввода по-прежнему помещается в очередь во входном буфере, а следующая nextLine () будет считывать оставшуюся часть целочисленной строки (которая пуста). – Neeraj Gahlawat 30 July 2017 в 03:50

Если вы хотите быстро сканировать входные данные, не запутавшись в методе nextLine () класса Scanner, используйте для этого специальный сканер ввода.

Код:

class ScanReader {
/**
* @author Nikunj Khokhar
*/
    private byte[] buf = new byte[4 * 1024];
    private int index;
    private BufferedInputStream in;
    private int total;

    public ScanReader(InputStream inputStream) {
        in = new BufferedInputStream(inputStream);
    }

    private int scan() throws IOException {
        if (index >= total) {
            index = 0;
            total = in.read(buf);
            if (total <= 0) return -1;
        }
        return buf[index++];
    }
    public char scanChar(){
        int c=scan();
        while (isWhiteSpace(c))c=scan();
        return (char)c;
    }


    public int scanInt() throws IOException {
        int integer = 0;
        int n = scan();
        while (isWhiteSpace(n)) n = scan();
        int neg = 1;
        if (n == '-') {
            neg = -1;
            n = scan();
        }
        while (!isWhiteSpace(n)) {
            if (n >= '0' && n <= '9') {
                integer *= 10;
                integer += n - '0';
                n = scan();
            }
        }
        return neg * integer;
    }

    public String scanString() throws IOException {
        int c = scan();
        while (isWhiteSpace(c)) c = scan();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = scan();
        } while (!isWhiteSpace(c));
        return res.toString();
    }

    private boolean isWhiteSpace(int n) {
        if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
        else return false;
    }

    public long scanLong() throws IOException {
        long integer = 0;
        int n = scan();
        while (isWhiteSpace(n)) n = scan();
        int neg = 1;
        if (n == '-') {
            neg = -1;
            n = scan();
        }
        while (!isWhiteSpace(n)) {
            if (n >= '0' && n <= '9') {
                integer *= 10;
                integer += n - '0';
                n = scan();
            }
        }
        return neg * integer;
    }

    public void scanLong(long[] A) throws IOException {
        for (int i = 0; i < A.length; i++) A[i] = scanLong();
    }

    public void scanInt(int[] A) throws IOException {
        for (int i = 0; i < A.length; i++) A[i] = scanInt();
    }

    public double scanDouble() throws IOException {
        int c = scan();
        while (isWhiteSpace(c)) c = scan();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = scan();
        }
        double res = 0;
        while (!isWhiteSpace(c) && c != '.') {
            if (c == 'e' || c == 'E') {
                return res * Math.pow(10, scanInt());
            }
            res *= 10;
            res += c - '0';
            c = scan();
        }
        if (c == '.') {
            c = scan();
            double m = 1;
            while (!isWhiteSpace(c)) {
                if (c == 'e' || c == 'E') {
                    return res * Math.pow(10, scanInt());
                }
                m /= 10;
                res += (c - '0') * m;
                c = scan();
            }
        }
        return res * sgn;
    }

}

Преимущества:

  • Сканирование Вход быстрее, чем BufferReader
  • Уменьшает сложность времени
  • Сбрасывает буфер для каждого следующего входа

Методы:

  • scanChar () - сканирование одиночного символа
  • scanInt () - scan Integer value
  • scanLong () - scan Длительное значение
  • scanString () - сканирование Строковое значение
  • scanDouble () - сканирование Двойное значение
  • scanInt (int [] array) - сканирует полный массив Array (Integer)
  • scanLong (long [] array) - сканирует полный массив (длинный)

Использование:

  1. Скопируйте данный код ниже вашего java-кода.
  2. Инициализировать объект для данного класса

ScanReader sc = new ScanReader(System.in); 3. Импортировать необходимые классы :

import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; 4. Выбросить IOException из вашего основного метода для обработки исключения 5. Использовать предоставленные методы. 6. Наслаждайтесь

Пример:

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
class Main{
    public static void main(String... as) throws IOException{
        ScanReader sc = new ScanReader(System.in);
        int a=sc.scanInt();
        System.out.println(a);
    }
}
class ScanReader....
4
ответ дан NIKUNJ KHOKHAR 15 August 2018 в 14:43
поделиться

Мое тестирование выработало те же результаты, что и Prine, однако я подумал об довольно простом обходном пути:

Используя BufferedReader#nextLine(), где вы Scanner#readLine(), избегаете этой ошибки. Возможно, вы даже можете написать свою собственную оболочку сканера, чтобы переопределить функцию readLine Scanner с помощью функции nextLine BufferedReader.

0
ответ дан SamJakob 15 August 2018 в 14:43
поделиться

Наверное, я очень опаздываю на вечеринку.

Как уже говорилось ранее, вызов input.nextLine() после получения вашего значения int решит вашу проблему. Причина, по которой ваш код не работал, заключается в том, что с вашего ввода (куда вы ввели int) ничего не оставалось хранить в string1.

Рассмотрим nextLine () как нечетный среди методов nextFoo () в классе Scanner. Давайте возьмем быстрый пример. Скажем, у нас есть две строки кода, подобные приведенным ниже:

int firstNumber = input.nextInt();
int secondNumber = input.nextInt();

Если мы вводим значение ниже (как одну строку ввода)

54 234

Значение нашей переменной firstNumber и secondNumber становится 54 и 234 соответственно. Причина, по которой это работает, заключается в том, что новый канал ( i.e\n ) НЕ НЕ автоматически генерируется, когда метод nextInt () принимает значения. Он просто берет «следующий int» и движется дальше. Это то же самое для остальных методов nextFoo (), за исключением nextLine ().

nextLine () генерирует новый фид строки сразу после принятия значения; это то, что означает @RohitJain, говоря, что новый канал «потребляется».

Наконец, метод next () просто берет ближайшую строку без создания новой строки; это делает это предпочтительным методом для взятия отдельных строк в одной и той же строке.

Надеюсь, это поможет ... Веселая кодировка!

0
ответ дан Taslim 15 August 2018 в 14:43
поделиться

Почему бы не использовать новый сканер для каждого чтения? Как показано ниже. При таком подходе вы не столкнетесь с вашей проблемой.

int i = new Scanner(System.in).nextInt();
-2
ответ дан Tobias Johansson 15 August 2018 в 14:43
поделиться
  • 1
    Но тогда вы должны закрыть Scanner, чтобы предотвратить утечку памяти. Трата времени? – TheCoffeeCup 8 October 2015 в 01:22
  • 2
    Разве GC не заботится об этом, если сканер обернут методом? Например: String getInput () {return new Scanner (System.in) .nextLine ()}; – Tobias Johansson 1 June 2016 в 22:14
  • 3
    Это абсолютно неверно. nextInt() не будет использовать новую строку, независимо от того, находится ли она в «новой», Scanner или уже используемый. – Dawood ibn Kareem 29 December 2016 в 21:55

Чтобы избежать этой проблемы, используйте nextLine(); сразу после nextInt();, поскольку это помогает очистить буфер. Когда вы нажимаете ENTER, nextInt(); не захватывает новую строку и, следовательно, позже пропускает код Scanner.

Scanner scanner =  new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
4
ответ дан Urvashi Gupta 15 August 2018 в 14:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: