Loading...
a.polyanska avatar a.polyanska 107 Точки

[Technical Issue] Java Basics - Каква е разликата между next() и nextLine()?

Здравейте,

Прочетох из нета за разликите между двата метода. Очевидно, обаче, не схващам нещо, защото не мога да разбера защо, когато решавам задачата и използвам next() ми се получава, а с nextLine() излизат неща, които не искам :) Става дума за задачата от домашното към Intro to Java за сортиране на масиви (задача 8)(да се зададат определен брой думи от конзолата и програмата да ги сортира по азбучен ред). Ето го кодът, който пиша:

import java.util.*;

public class Problem08_SortArrayOfStrings {
    
    public static void main(String[] args){
        int n;

        Scanner input = new Scanner(System.in);
        System.out.print("Enter a number n: ");
        n = input.nextInt();
        
        String[] words = new String[n];
        
        for (int i = 0; i < n; i++) {
            System.out.print("Enter a word: ");
            words[i] = input.nextLine();        
        }
        Arrays.sort(words);
        
        System.out.println(Arrays.toString(words));
    }
}

Когато по този начин е зададено да се пълни масивът от конзолата, ми излиза два пъти един след друг написано "Enter a word", с възможност да се впише само един стринг, след което след сортирането винаги първото място в новия масив е празно:

Enter a number n: 3
Enter a word: Enter a word: abc
Enter a word: cde
[, abc, cde]

Когато заменя nextLine с next няма проблем и работи коректно. Не разбирам, обаче, защо. Някой може ли да ми обясни?

Тагове:
1
Java Advanced 15/09/2014 21:55:20
a.angelov avatar a.angelov 1316 Точки

Ще се повторя от снощи, но - сложи едно input.nextLine() на мястото където съм го сложил аз и програмата ще ти работи нормално:

  Scanner input = new Scanner(System.in);
        System.out.print("Enter a number n: ");
        n = input.nextInt();

        input.nextLine();

        
        String[] words = new String[n];
        
        for (int i = 0; i < n; i++) {
            System.out.print("Enter a word: ");
            words[i] = input.nextLine();        
        }
        Arrays.sort(words);

 

Снощи отговорих на друга колежка в тази тема: https://softuni.bg/forum/questions/details/886/5/10 - може да погледнеш и там в последните коментари.

 

Ето какво пише в документацията за NextLine():

public String nextLine()
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.

Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.

Тоест - този метод чете текущия ред до символа за нов ред в края. next() чете само следващия token.

Причината да не работи в твоя код NextLine() е, че има един остатъчен символ за нов ред останал след прочитането на nextInt() и реално при първото минаване на цикъла nextLine() хваща него - тоест първото ти прочитане е празно.

Като сложиш един input.nextLine() преди цикъла прихващаш буферирания символ за нов ред и програмата работи коректно.

4
05/09/2014 23:37:34
a.polyanska avatar a.polyanska 107 Точки

Отново не ми отваря линка :) И аз налучках как работи, но ми се ще да знам защо :) Можеш ли да ми обясниш по-подробно или дами дадеш работещ линк или заглавие на темата, която дублирам?

0
a.angelov avatar a.angelov 1316 Точки

Оправих уж линка...

Темата е темата за домашното от миналия курс - има ги стикнати горе във важните теми:

Списък с домашните към курса Java Basics - септември 2014

Там има линк към старите домашни.

0
05/09/2014 23:40:26
a.polyanska avatar a.polyanska 107 Точки

Мисля, че схванах идеята. Благодаря ти много!

0
milen_vm avatar milen_vm 68 Точки

Причината за да се случва това е че когато четеш от конзолата n с input.nextInt(), метода nextInt() 'хвърля' един празен ред в конзолата и този разен ред се прочита от words[i] = input.nextLine() - това е празният елемент в масива. Колегата a.angelov ти е предложил да добавиш input.nextLine(); след като прочетеш n за да може този празен ред да се 'глътне' от инпута без да се запазва в някъква променлива. След което си четеш стринговете нормално от конзолата. Това е типичен проблем при четене от конзолата и трябва да се внимава когато се чете нещо с nextInt или nextFloat а след това се използва метода nextLine.

1
06/09/2014 00:13:07
a.polyanska avatar a.polyanska 107 Точки

T.e. когато се използва nextInt или nextFloat, то от конзолата се прочита (а после и запазва в две различни променливи ) следващото число + нов ред, така ли?

0
milen_vm avatar milen_vm 68 Точки

След като прочетеш инта for цикъла, с който пълниш масива се завърта изписва ти "Enter a word: ", но не ти дава да въвеждаш нищо защто новият ред които остава се записва като първи елемент в масива и при второто завъртане на цикъла отново изписва "Enter a word: " (от тук идва двоиното изписване) и вече те чака да въведеш дума.

input.nextLine(); който трябва да сложиш след като прочетеш n обира този празен ред и на конзолата вече няма нищо което да се прочере автоматично от nextLine() метода в цикъла.

 

1
05/09/2014 23:50:49
nikola.m.nikolov avatar nikola.m.nikolov 830 Точки

Другият вариант е вместо nextInt() да използваш Integer.parseInt(input.nextLine());

4
05/09/2014 23:35:45
Filkolev avatar Filkolev 4482 Точки

Това е май най-чистият вариант. Само че трябва да се внимава на реда да се въведе само числото, защото всякакви спейсове ще изгърмят.

0
nikola.m.nikolov avatar nikola.m.nikolov 830 Точки

Винаги може да се използва .trim()

Integer.parseInt(input.nextLine().trim())

 

0
06/09/2014 10:10:33
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.