Java-программа, которая вводит 5 имен и классов студентов, а затем печатает средний класс, а также имя и класс высших и младших классов [dубликат]

Вы можете создать скрипт, который проверяет, работает ли пользователь с правами root или нет. Затем он запустит команду systemctl или возвращает ошибку.

#!/bin/bash if [ "$(whoami)" != "root" ]; then echo "Sorry, you are not root." exit 1 else (systemctl shutdown command) fi

Источник

490
задан 4 April 2018 в 16:31

14 ответов

Если вы хотите прочитать как строки, так и 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
ответ дан 15 August 2018 в 15:37

Вместо 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
ответ дан 15 August 2018 в 15:37

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

1
ответ дан 15 August 2018 в 15:37

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

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

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

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

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

33
ответ дан 15 August 2018 в 15:37

Проблема заключается в методе 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
ответ дан 15 August 2018 в 15:37

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

текст, который представляет несколько строк, также содержит непечатаемые символы между строками (мы называем их разделителями строк), как возврат каретки (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, либо

, который представляет несколько строк, также содержит непечатаемые символы между строками (мы называем их разделителями строк), как возврат каретки (CR - в строковых литералах, представленных в виде "\r") line feed (LF - в строковых литералах, представленных как "\n") не используют nextInt (ни next, ни какие-либо методы nextTYPE). Вместо этого прочитайте целые строки данных по строке nextLine и номера разбора из каждой строки (при условии, что одна строка содержит только одно число) для правильного типа, например int через Integer.parseInt.

он также будет кэшировать эти разделители строк внутри : 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
ответ дан 15 August 2018 в 15:37

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

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

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

23
ответ дан 15 August 2018 в 15:37
[F1]
0
ответ дан 15 August 2018 в 15:37
  • 1
    Если вы используете метод nextLine () сразу после метода nextInt (), напомните, что nextInt () читает целые числа; из-за этого последний символ новой строки для этой строки целочисленного ввода по-прежнему помещается в очередь во входном буфере, а следующая nextLine () будет считывать оставшуюся часть целочисленной строки (которая пуста). – Neeraj Gahlawat 30 July 2017 в 06: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 Уменьшает сложность времени Сбрасывает буфер для каждого следующего ввода

Методы :

Сканирование Вход быстрее, чем BufferReader scanInt () - проверка Целочисленное значение Уменьшает сложность времени scanString () - сканирование Строковое значение Сбрасывает буфер для каждый следующий вход scanInt (int [] array) - сканирует полный массив (Integer) scanLong (long [] array) - сканирует полный массив (длинный)

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

Скопируйте данный код под кодом Java. Инициализировать объект для данного класса

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
ответ дан 15 August 2018 в 15:37

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

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

0
ответ дан 15 August 2018 в 15:37

Я догадываюсь, что я очень опаздываю на вечеринку ..

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

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

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

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

54 234

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

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

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

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

0
ответ дан 15 August 2018 в 15:37

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

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

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

Scanner scanner =  new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
4
ответ дан 15 August 2018 в 15:37

Другие вопросы по тегам:

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