У чому різниця між методами next () і nextLine () від класу Scanner?


87

У чому головна різниця між next()і nextLine()?
Моя головна мета - прочитати весь текст за допомогою, Scannerякий може бути "підключений" до будь-якого джерела (наприклад, файлу).

Якого з них вибрати і чому?


Це може допомогти вам [Використання scanner.nextLine ()] [1]: stackoverflow.com/questions/5032356/using-scanner-nextline
Milaci

Відповіді:


86

Я завжди вважаю за краще читати введення за допомогою, nextLine()а потім аналізувати рядок.

Використання next()поверне лише те, що стоїть перед роздільником (за замовчуванням пробіли). nextLine()автоматично повертає сканер вниз після повернення поточного рядка.

Корисним інструментом для аналізу даних з nextLine()буде str.split("\\s+").

String data = scanner.nextLine();
String[] pieces = data.split("\\s+");
// Parse the pieces

Для отримання додаткової інформації щодо класу Scanner або String зверніться до наступних посилань.

Сканер: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

Рядок: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html


5
То чому б просто не використовувати a BufferedReaderдля читання рядків за рядком? Я не розумію, чому Scannerв такій моді.
Девід Конрад

7
@DavidConrad "Яка різниця між методами next () і nextLine () від класу Scanner?"
Трістан

4
Так, я розумію, що це те, про що запитував ОП, мені було просто цікаво, оскільки ти кажеш, що "завжди волієш" використовувати nextLine.
Девід Конрад

Ви можете спокійно зробити nextLine (), а потім створити новий Сканер саме для цієї лінії. Клас Сканер може сканувати рядки: новий Сканер (новий Сканер (System.in) .nextLine ()).
axell13

47

next()може прочитати введення лише до пробілу. Він не може прочитати два слова, розділені пробілом. Крім того, next()розміщує курсор в одному рядку після прочитання вводу.

nextLine()читає введення, включаючи пробіл між словами (тобто читається до кінця рядка \n). Після прочитання введення nextLine()курсор розміщується в наступному рядку.

Для читання цілого рядка ви можете використовувати nextLine().


@LuiggiMendoza ви маєте на увазі форматування, а не офіційне написання?
Det

next () може читати введення лише до пробілу . Він не може прочитати два слова, розділені пробілами . пробіл включає пробіл, вкладку та подачу лінії
Фред Ху

18

З JavaDoc:

  • A Scannerрозбиває свій вхід на маркери, використовуючи шаблон роздільника, який за замовчуванням відповідає пробілу.
  • next(): Знаходить і повертає наступний повний маркер із цього сканера.
  • nextLine(): Просуває цей сканер за поточним рядком і повертає пропущені дані.

Тож у випадку "small example<eol>text" next()слід повернути "малий" і nextLine()повинен повернути "малий приклад"


1
чому не next()включає \nу повернутий маркер ??
rimalonfire

1
Це питання до дизайнерів Java API або надішліть запитання на SO, і, можливо, хтось знає, чому.
Олег Скляр

10

Те, що я помітив, крім next () сканує лише простір, де як nextLine () сканує весь рядок, це те, що наступний чекає, поки не отримає повний маркер, де nextLine () не чекає повного маркера, коли-небудь '\ n' (тобто при натисканні клавіші Enter) курсор сканера переходить до наступного рядка і повертає попередній пропущений рядок. Він не перевіряє, чи дали ви повний ввід чи ні, навіть він буде приймати порожній рядок, де як next () не бере порожній рядок

public class ScannerTest {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int cases = sc.nextInt();
        String []str = new String[cases];
        for(int i=0;i<cases;i++){
            str[i]=sc.next();
        }
     }

}

Спробуйте цю програму, змінивши наступний () і nextLine () у циклі for, продовжуйте натискати клавішу \ \ n, яка є клавішею введення, без будь-якого вводу; ви можете виявити, що за допомогою методу nextLine () вона завершується після натискання заданої кількості випадків, коли оскільки next () не припиняється, доки ви не надасте та не введете його для заданої кількості випадків.


1
Дуже цікавий приклад. Запустивши код, я нарешті побачив, як це next()працює на практиці, він ігнорує клавішу enter, тоді як nexLine()приймає його як повне введення, і він копіює його на консоль, якщо ви повторите значення захопленого. Я щойно додав System.out.println(str[i]);як новий рядок нижче str[i]=sc.next();абоstr[i]=sc.nextLine();
Пабло

@PabloAdames вдячний, якщо ти можеш проголосувати за відповідь, якщо тобі так подобається
Муралі Кріш

9

Ключовим моментом є пошук місця, де метод зупиниться, і де буде курсор після виклику методів.

Усі методи читатимуть інформацію, яка не включає пробіли між позицією курсора та наступними роздільниками за замовчуванням (пробіли, вкладка, \ n - створена натисканням клавіші Enter). Курсор зупиняється перед роздільниками, за винятком nextLine(), що зчитує інформацію (включаючи пробіли, створені роздільниками) між положенням курсора та \ n, а курсор зупиняється ззаду \ n.


Наприклад, розглянемо наступну ілюстрацію:

|23_24_25_26_27\n

| -> поточне положення курсору

_ -> пробіли

потік -> Жирний (інформація, отримана методом виклику)

Подивіться, що відбувається, коли ви викликаєте ці методи:

nextInt()    

читати 23 | _24_25_26_27 \ n

nextDouble()

читати 23_ 24 | _25_26_27 \ n

next()

читати 23_24_ 25 | _26_27 \ n

nextLine()

читати 23_24_25 _26_27 \ n |


Після цього слід викликати метод залежно від ваших потреб.


2
така недооцінена відповідь. все інше трохи вводить в оману
csguy

3

Коротше кажучи: якщо ви вводите масив рядків довжиною t, тоді Scanner # nextLine () очікує t рядків, кожен запис у масиві рядків диференціюється від іншого за допомогою клавіші enter. А Scanner # next () продовжуватиме приймати вводи до ви натискаєте клавішу Enter, але зберігаєте рядок (слово) всередині масиву, який відокремлюється пробілами.

Давайте подивимось на наступний фрагмент коду

    Scanner in = new Scanner(System.in);
    int t = in.nextInt();
    String[] s = new String[t];

    for (int i = 0; i < t; i++) {
        s[i] = in.next();
    }

коли я запускаю вище фрагмент коду в моїй IDE (скажімо, довжина рядка 2), не має значення, чи ввожу я свій рядок як

Введіть як: - abcd abcd або

Введіть як: -

а Б В Г

а Б В Г

Вихідні дані будуть як abcd

а Б В Г

Але якщо в тому ж коді ми замінюємо метод next () на nextLine ()

    Scanner in = new Scanner(System.in);
    int t = in.nextInt();
    String[] s = new String[t];

    for (int i = 0; i < t; i++) {
        s[i] = in.nextLine();
    }

Тоді, якщо ви введете введення в підказці як - abcd abcd

Вихід: -

abcd abcd

і якщо ви введете введення в підказці як abcd (і якщо натиснете Enter, щоб ввести наступний abcd в іншому рядку, вхідне підказка просто вийде, і ви отримаєте результат)

Вихід: -

а Б В Г


2

З javadocs

next () Повертає наступний маркер, якщо він відповідає шаблону, побудованому із зазначеного рядка. nextLine () Просуває цей сканер за поточним рядком і повертає пропущені дані.

Який із них вибрати, залежить від того, який найбільше відповідає вашим потребам. Якби я читав цілий файл, я б пішов на nextLine, поки не отримав весь файл.


1

З документації для сканера :

Сканер розбиває свої дані на маркери, використовуючи шаблон роздільника, який за замовчуванням відповідає пробілу.

З документації для next () :

Перед повним маркером передує введення, яке відповідає шаблону роздільника.


1

Методи next () і nextLine () пов'язані зі сканером і використовуються для отримання вхідних даних рядка. Їх відмінності полягають у ...

next () може читати введення лише до пробілу. Він не може прочитати два слова, розділені пробілом. Крім того, next () розміщує курсор у тому самому рядку після прочитання вводу.

nextLine () читає введення, включаючи пробіл між словами (тобто читає до кінця рядка \ n). Після прочитання введення, nextLine () розміщує курсор у наступному рядку.

import java.util.Scanner;

public class temp
{
    public static void main(String arg[])
    {
        Scanner sc=new Scanner(System.in);
        System.out.println("enter string for c");
        String c=sc.next();
        System.out.println("c is "+c);
        System.out.println("enter string for d");
        String d=sc.next();
        System.out.println("d is "+d);
    }
}

Вихід:

введіть рядок для c abc def
c є abc

введіть рядок для d

d - деф

Якщо ви використовуєте nextLine () замість next (), тоді

Вихід:

введіть рядок для c

ABC DEF
c - це ABC DEF
ввести рядок для d

GHI
d - це GHI


1
  • Тільки для іншого прикладу Scanner.next () і nextLine () є такий, як показано нижче: nextLine () не дозволяє користувачеві вводити, тоді як next () змушує Scanner чекати і читати введення.

     Scanner sc = new Scanner(System.in);
    
     do {
        System.out.println("The values on dice are :");
        for(int i = 0; i < n; i++) {
            System.out.println(ran.nextInt(6) + 1);
        }
        System.out.println("Continue : yes or no");
     } while(sc.next().equals("yes"));
    // while(sc.nextLine().equals("yes"));
    

1

Сканер розбиває свої дані на маркери, використовуючи шаблон роздільника, який за замовчуванням відомий як пробіли .

Next () використовує для читання одного слова, і коли він отримує пробіл, він припиняє читання і курсор повертається у вихідне положення. NextLine (), хоча цей читає ціле слово, навіть коли він зустрічається з пробілом. Курсор зупиняється, коли закінчує читати, і курсор повертається до кінця рядка. тому вам не потрібно використовувати деліметр, коли ви хочете прочитати повне слово як речення. вам просто потрібно використовувати NextLine ().

 public static void main(String[] args) {
            // TODO code application logic here
           String str;
            Scanner input = new Scanner( System.in );
            str=input.nextLine();
            System.out.println(str);
       }

1

Обидві функції використовуються для переходу до наступного маркера сканера.

Різниця полягає в тому, як генерується маркер сканера

next () генерує маркери сканера з використанням роздільника як пробілу

nextLine () генерує маркери сканера, використовуючи роздільник як '\ n' (тобто введіть натискання клавіш)


0

У мене також виникла проблема з роздільником. Питання було все про вхідні дані

  1. введіть ім'я.
  2. введіть свій вік.
  3. введіть свою електронну адресу.
  4. введіть свою адресу.

Проблема

  1. Я успішно закінчив з іменем, віком та електронною поштою.
  2. Коли я придумав адресу двох слів, що мають пробіли (вулиця Гарнет), я щойно отримав перше "харнет".

Рішення

Я використав роздільник для мого сканера і вийшов успішним.

Приклад

 public static void main (String args[]){
     //Initialize the Scanner this way so that it delimits input using a new line character.
    Scanner s = new Scanner(System.in).useDelimiter("\n");
    System.out.println("Enter Your Name: ");
    String name = s.next();
    System.out.println("Enter Your Age: ");
    int age = s.nextInt();
    System.out.println("Enter Your E-mail: ");
    String email = s.next();
    System.out.println("Enter Your Address: ");
    String address = s.next();

    System.out.println("Name: "+name);
    System.out.println("Age: "+age);
    System.out.println("E-mail: "+email);
    System.out.println("Address: "+address);
}

0

Основна різниця next () використовується для отримання вхідних даних, поки не зустрінеться роздільник (за замовчуванням це пробіли, але ви також можете його змінити) і поверніть введений маркер. Курсор залишається в тому ж рядку. Тоді як у nextLine () він сканує вхідні дані, доки ми не натиснемо кнопку Enter і не повернемо все, а курсор помістимо в наступний рядок. **

        Scanner sc=new Scanner(System.in);
        String s[]=new String[2];
        for(int i=0;i<2;i++){
            s[i]=sc.next();
        }
        for(int j=0;j<2;j++)
        {
            System.out.println("The string at position "+j+ " is "+s[j]);
        }

**

Спробуйте запустити цей код, вказавши Input як "Hello World". Сканер зчитує вхід до 'o', а потім виникає роздільник. Так s [0] буде "Hello", а курсор буде вказувати на наступну позицію після роздільника ( це "W" у нашому випадку), а коли s [1] читається, він сканує "Світ" і повертає його до s [1] як наступний повний маркер (за визначенням Сканера). Якщо ми використовуємо nextLine () натомість він буде читати "Hello World" повністю, а також більше, поки ми не натиснемо кнопку введення і збережемо її в s [0]. Ми можемо дати ще один рядок, також використовуючи nextLine (). Я рекомендую вам спробувати скористатися цим прикладом та іншим та попросити пояснити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.