Этот новый пакет https://github.com/a-lucas/angular.js-server позволяет предварительно обработать угловое приложение и отправить HTML клиенту, который затем выполнит jS-код.
Он поддерживает кэширование на URL-адрес, и вы можете определить правила для активации предварительного рендеринга URL.
PS: Я являюсь основным источником этого пакета.
Это потому, что метод 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();
Если вы хотите прочитать обе строки и 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();
Вместо 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();
}
sc.nextLine()
лучше по сравнению с анализом ввода. Потому что производительность разумна, это будет хорошо.
Это потому, что, когда вы вводите номер, нажмите «Ввод», input.nextInt()
потребляет только номер, а не «конец строки». Когда input.nextLine()
выполняется, он потребляет «конец строки» все еще в буфере с первого входа.
Вместо этого используйте input.nextLine()
сразу после input.nextInt()
Кажется, есть много вопросов об этой проблеме с java.util.Scanner
. Я думаю, что более читаемым / идиоматическим решением было бы вызвать scanner.skip("[\r\n]+")
, чтобы удалить любые символы новой строки после вызова nextInt()
.
ИЗМЕНИТЬ: как показано ниже, как @PatrickParker, это вызовет бесконечный цикл, если пользовательские входы любые пробелы после номера. См. Их ответ на лучший шаблон для использования с пропуском: https://stackoverflow.com/a/42471816/143585
Проблема заключается в методе 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();
nextLine
, но мне все еще нужно объяснение этого поведения
– Eng.Fouad
14 August 2011 в 13:25
Что вам нужно знать:
"\r"
) line line (LF - в строковых литералах, представленных как "\n"
) 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
.
Он делает это, потому что input.nextInt();
не фиксирует новую строку. вы могли бы сделать, как и другие, добавив под ним input.nextLine();
. В качестве альтернативы вы можете сделать это в стиле C # и разобрать nextLine на целое число так:
int number = Integer.parseInt(input.nextLine());
Выполнение этого работает так же хорошо, и оно сохраняет строку кода.
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);
}
Если вы хотите быстро сканировать входные данные, не запутавшись в методе 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;
}
}
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....
Мое тестирование выработало те же результаты, что и Prine, однако я подумал об довольно простом обходном пути:
Используя BufferedReader#nextLine()
, где вы Scanner#readLine()
, избегаете этой ошибки. Возможно, вы даже можете написать свою собственную оболочку сканера, чтобы переопределить функцию readLine Scanner с помощью функции nextLine BufferedReader.
Наверное, я очень опаздываю на вечеринку.
Как уже говорилось ранее, вызов input.nextLine()
после получения вашего значения int решит вашу проблему. Причина, по которой ваш код не работал, заключается в том, что с вашего ввода (куда вы ввели int) ничего не оставалось хранить в string1
.
Рассмотрим nextLine () как нечетный среди методов nextFoo () в классе Scanner. Давайте возьмем быстрый пример. Скажем, у нас есть две строки кода, подобные приведенным ниже:
int firstNumber = input.nextInt();
int secondNumber = input.nextInt();
Если мы вводим значение ниже (как одну строку ввода)
54 234
blockquote>Значение нашей переменной
firstNumber
иsecondNumber
становится 54 и 234 соответственно. Причина, по которой это работает, заключается в том, что новый канал ( i.e\n ) НЕ НЕ автоматически генерируется, когда метод nextInt () принимает значения. Он просто берет «следующий int» и движется дальше. Это то же самое для остальных методов nextFoo (), за исключением nextLine ().nextLine () генерирует новый фид строки сразу после принятия значения; это то, что означает @RohitJain, говоря, что новый канал «потребляется».
Наконец, метод next () просто берет ближайшую строку без создания новой строки; это делает это предпочтительным методом для взятия отдельных строк в одной и той же строке.
Надеюсь, это поможет ... Веселая кодировка!
Почему бы не использовать новый сканер для каждого чтения? Как показано ниже. При таком подходе вы не столкнетесь с вашей проблемой.
int i = new Scanner(System.in).nextInt();
Scanner
, чтобы предотвратить утечку памяти. Трата времени?
– TheCoffeeCup
8 October 2015 в 01:22
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
option = Integer.parseInt(input.nextLine());}
вместо полногоtry{...}
? Есть ли недостаток в использовании только выше? – blekione 27 October 2012 в 18:52try-catch
, потому чтоInteger.parseInt
выбрасываетNumberFormatException
, когда ему передается недопустимый аргумент. Вы узнаете об исключении позже. Для E.G: -Integer.parseInt("abc")
. Вы не хотите & quot; abc & quot; чтобы преобразовать в int правильно? – Rohit Jain 27 October 2012 в 19:02