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

У меня есть ощущение, что проблема в цикле while и что сканер не работает, но я не уверен.

import java.util.Scanner;

public class LIBBOOKS {

    public static void main(String[] args)
    {
        int numB = 0;
        int count = 0;;
        boolean libEmpty = true;
        String nameArray[];
        String bookName = "";

        System.out.println("Enter Number of Books: ");
        Scanner value = new Scanner(System.in);     
        numB = value.nextInt();

        nameArray = new String[numB];

        while(libEmpty)
        {
            Scanner sValue = new Scanner(System.in);
            System.out.println("Enter Book Name: ");
            while(sValue.hasNextLine())
            {
                bookName = sValue.nextLine();
            }

            count++;
            nameArray[count] = bookName;
            if(numB < count)
            {
                System.out.println("Capacity Reached");
                libEmpty = false;
            }
            sValue.close();
        } 

        value.close();
        System.out.println("Book Listing Entered:");
        for(int i = 1; i > count; i++)
        {
            System.out.println(" " + nameArray[i]);
        }

    }

}

Когда я запускаю программу, это то, что я получаю:

Enter Number of Books: 
4
Enter Book Name: 
apples
corn
peaches
oranges

Программа должна спрашивать меня каждый раз, какое имя, прежде чем я получу возможность ввести другое имя. Что я ожидаю, что произойдет:

Enter Number of Books:
4
Enter Book Name:
apples
Enter Book Name:
corn
Enter Book Name:
peaches
Enter Book Name:
oranges

Capacity Reached
Book Listing Entered:
corn apples peaches oranges
-1
John Perry 28 Май 2017 в 05:13

2 ответа

Лучший ответ

Есть несколько проблем с этим кодом. Вы создаете несколько сканеров. В них нет необходимости, и хотя они могут не причинить вам вреда, вам нужно просто создать:

Scanner scanner = new Scanner(System.in);

Ваше имя класса не соответствует соглашениям об именах Java, которые используются в смешанном регистре для имен классов. Есть несколько других незначительных проблем стиля, о которых я упомяну позже.

Но две самые большие проблемы заключаются в том, что вы не очищаете завершающий символ новой строки после того, как прочитали количество книг, и что вы читаете названия книг в тесном цикле, ничего не делая с ними.

Когда вы используете scanner.nextInt(), сканер прочитает число и остановится, как только достигнет конца этого числа, даже если вы набрали целую строку.

Предположим, вы набрали 4 и нажали Enter. В буфере находятся следующие символы: 4 \n

Сканер прочитает только 4, преобразует их в int и возвращает. В следующий раз, когда вы позвоните scanner.nextLine(), он увидит \n и вернет пустую строку. Это означает, что вам нужно очистить эту новую строку, прежде чем пытаться читать в названиях книг. Вы можете сделать это с помощью вызова scanner.nextLine().

Если бы не ваша другая ошибка, вы бы спросили нас, почему имя первой книги пустое. Теперь перейдем к другой ошибке.

System.out.println("Enter Book Name: ");
while (scanner.hasNextLine())
{
    bookName = scanner.nextLine();
}

Этот код выполняет чтение строки, отбрасывает ее, читает другую строку, отбрасывает ее и так далее до бесконечности. Единственный способ, которым это закончится, это если он достигнет конца файла, чего не произойдет, поскольку вы читаете из терминала, а не из файла, или если вы убьете JVM, нажав Ctrl-C.

Вы продолжаете читать названия книг, но ничего с ними не делаете. И ваш вопрос говорит, что вы ожидаете, что вам будет предложено каждый раз, но подсказка не в цикле. Что вы хотите сделать, это что-то вроде этого:

scanner.nextLine(); // clear the newline after the number of books
while (count < numB)
{
    System.out.println("Enter Book Name:");
    bookName = scanner.nextLine();
    nameArray[count] = bookName;
    count++;
}

За исключением того, что нет никакой причины для существования переменной bookName. Он используется только для того, чтобы взять имя, а затем поместить его в массив. С тем же успехом вы можете просто читать прямо в массив:

scanner.nextLine(); // clear the newline after the number of books
while (count < numB)
{
    System.out.println("Enter Book Name:");
    nameArray[count] = scanner.nextLine();
    count++;
}

Теперь есть еще одна ошибка, с которой вы столкнетесь после прочтения книг, но сначала один небольшой момент о сканере. Это вам не больно, но это не совсем правильно:

scanner.close();

Вы не хотите закрывать этот сканер. Это хорошая привычка закрывать файлы, но есть принцип, когда вы должны что-то закрывать, и это так: вы должны закрывать все, что открываете, но только то, что открываете.

Вы не открыли System.in. Вы просто обернули вокруг него Scanner. Итак, потому что вы не открыли его, вы не хотите закрывать его. Поскольку закрытие терминала на самом деле ничего не делает, здесь нет никакого вреда, но это не совсем правильно.

С другой стороны, если вы открыли FileInputStream и обернули Scanner вокруг этого , вы определенно захотите закрыть сканер, чтобы открываемый вами файл закроется должным образом.

Хорошо, теперь на распечатке книг!

for (int i = 1; i > count; i++)
{
    System.out.println(" " + nameArray[i]);
}

Здесь есть две разные проблемы. Во-первых, условия вашего цикла неверны. Вы хотите начать с 0 и продолжить, пока i меньше nameArray.length. (count и numB должны иметь то же значение, что и nameArray.length, но массив знает, сколько он длится, поэтому вам следует полагаться на это, а не на переменную, которая может иметь такое же значение.) Вот как будет выглядеть правильный цикл for:

for (int i = 0; i < nameArray.length; i++)
{
    System.out.println(" " + nameArray[i]);
}

Однако с тех пор, как в Java 5 появился лучший способ: Enhanced For Loop:

for (String bookName : nameArray)
{
    System.out.println(" " + bookName);
}

Таким образом, нет опасности ошибиться с индексами массива.

И последнее замечание: называть сложно, и в выбранных вами именах нет ничего плохого, но я бы назвал массив books и название книги title, поэтому я бы написал этот последний цикл:

for (String title : books) {
    System.out.println(" " + title);
}
2
David Conrad 28 Май 2017 в 03:53

Просто обрежьте эту строку:

System.out.println("Enter Book Name: ");

И вставьте его в цикл, где вы вводите названия книг:

while(sValue.hasNextLine())
  {
     System.out.println("Enter Book Name: ");
     bookName = sValue.nextLine();
  }
2
A. Cucci 28 Май 2017 в 02:34