You are here: Home » Учебник » Чтение ввода с консоли

Чтение ввода с консоли

Ключевой момент: чтение ввода с консоли даёт возможность программе принимать ввод от пользователя

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

Java использует System.out для обращения к стандартному устройству вывода и System.in для стандартного устройства ввода. По умолчанию, устройство вывода – это дисплей монитора, а устройство ввода – это клавиатура. Для выполнения консольного вывода, вы просто используете метод println для отображения в консоль простых значений или строк. Консольный ввод не поддерживается напрямую в Java, но вы можете использовать класс Scanner для создания объекта для чтения ввода из System.in. Это делается так:

Scanner input = new Scanner(System.in);

Синтаксис new Scanner(System.in) создаёт объект типа Scanner. Синтаксис Scanner input объявляет, что input является переменной, чей тип – Scanner. Вся строка Scanner input = new Scanner(System.in) создаёт объект Scanner и присваивает его ссылку переменной input. Объект может вызывать свои методы. Вызвать метод объекта означает запросить объект выполнить задачу. Вы можете вызвать метод nextDouble() для чтения значения double следующим образом:

double radius = input.nextDouble();

Инструкция считывает число с клавиатуры и присваивает это число переменной radius. Перепишем программу из предыдущего урока, чтобы она запрашивала радиус у пользователя:

import java.util.Scanner; // Scanner находится в пакете java.util

public class ComputeAreaWithConsoleInput {

    public static void main(String[] args) {
        // Создаём объект Scanner
        Scanner input = new Scanner(System.in);
        // Запрос пользователю на ввод радиуса
        System.out.print("Введите радиус: ");
        double radius = input.nextDouble();
        // Вычисление площади
        double area = radius * radius * 3.14159;
        // Отображение результата
        System.out.println("Площадь круга радиусом "
                + radius + " равна " + area);
    }
}

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

Строка 10 отображает в консоли надпись «Введите радиус: ». Это называется prompt (подсказка, напоминание), поскольку он направляет пользователя к вводу данных. Если ваша программа ожидает ввода с клавиатуры, она всегда должна говорить пользователю, ввод каких данных от него ожидается.

print или println

Метод print на десятой строке

System.out.print("Введите радиус: ");

идентичен методу println с той лишь разницей, что println переходит к началу новой строки после отображения строки, а print после вывода не переходит к следующей строке.

Строка 8 создаёт объект Scanner. Инструкция на одиннадцатой строке  считывает ввод с клавиатуры.

double radius = input.nextDouble();

После того, как пользователь ввёл число и нажал клавишу Ввод (Enter), программа считывает число и присваивает его переменной radius.

Больше подробностей об объектах будет представлено в одной из последующих главах. На текущий момент просто примите, что это то, как получить вход с консоли.

Конкретный импорт

Класс Scanner находится в пакете java.util. Он импортируется на строке 2. Имеется два вида инструкций import: конкретный импорт и импорт с подстановочными символами. Конкретный импорт импортирует определённый единичный класс в инструкции import. Например, следующая инструкция импортирует Scanner из пакета java.util.

import java.util.Scanner;

Импорт с подстановочным символом

Импорт с подстановочным символом импортирует все классы из пакета, используя звёздочку в качестве подстановочного символа. Например, следующая инструкция импортирует все классы из пакета java.util.

import java.uitl.*;

Разница в производительности между импортом одного класса или всех классов в пакете

Информация для классов из импортируемого пакета не считывается во время компиляции или во время выполнения если класс в программе не используется. Инструкция import просто говорит компьютеру, где расположен класс. Нет разницы в производительности между конкретным импортом или импортом с подстановочным символом.

Ещё одна программа, которая даёт пример чтения нескольких значений с клавиатуры. Программа считывает три числа и показывает их среднее арифметическое:

import java.util.Scanner; // Scanner из пакета java.util

public class ComputeAverage {

    public static void main(String[] args) {
        // Создание объекта Scanner
        Scanner input = new Scanner(System.in);
        // Запрос пользователю ввести три числа
        System.out.print("Введите три числа: ");
        double number1 = input.nextDouble();
        double number2 = input.nextDouble();
        double number3 = input.nextDouble();
        // Вычисление средней
        double average = (number1 + number2 + number3) / 3;
        // Вывод результата
        System.out.println("Среднее числе " + number1 + " " + number2
                + " " + number3 + " равно " + average);
    }
}

Листинг с номерами строк:

Код для импорта класса Scanner (строка 2) и создание объекта Scanner (строка 8) такие же, как и в предшествующем примере, как и во всех новых программах, которые вы будете писать, для чтения ввода с клавиатуры.

Строка 10 делает запрос пользователю ввести три числа. Числа считываются на строках 11-13. Вы можете ввести три числа разделив их пробелами, а затем нажать кнопку Enter, или нажимать клавишу Enter после каждого числа. Оба варианта показаны в примерах запуска этой программы.

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

Примечание: большинство программа в начальных главах этого сайта выполняют три шага – ввод, обработка и вывод, это также называется IPO (от английских input, process, and output). Ввод – это получение данных от пользователя; обработка – это выработка результата, используя ввод, а вывод – это отображение результатов.

Решение проблемы с ошибкой InputMismatchException

Если при попытке ввести число с плавающей точкой, например, такой строкой программы:

double radius = input.nextDouble();

Вы получаете ошибку:

Exception in thread "main" java.util.InputMismatchException
	at java.util.Scanner.throwFor(Scanner.java:864)
	at java.util.Scanner.next(Scanner.java:1485)
	at java.util.Scanner.nextDouble(Scanner.java:2413)
	at ComputeAreaWithConsoleInput.main(ComputeAreaWithConsoleInput.java:10)

Это означает, что локаль* вашей системы в качестве десятичного разделителя ожидает не точку, а запятую (или наоборот).

*Региональный стандарт, региональные настройки (проф. жарг. лока́ль от англ. locale, /lɔ.kal/ или /ləuˈkɑ:l/) — набор параметров, определяющий региональные настройки пользовательского интерфейса, такие как язык, страна, часовой пояс, набор символов и т. п.

Выходов из этой ситуации два:

  • использовать десятичный разделитель вашей локали (точку вместо запятой или запятую вместо точки)
  • чуть изменить программу – явно указать локаль

Для этого при создании объекта Scanner добавьте .useLocale(Locale.US). Например, объект создавался следующим образом:

Scanner input = new Scanner(System.in);

После дополнения получается такая строка создания объекта:

Scanner input = new Scanner(System.in).useLocale(Locale.US);

Также в начале программы требуется сделать дополнительный импорт:

import java.util.Locale;

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

import java.util.Scanner; // Scanner находится в пакете java.util
import java.util.Locale;

public class ComputeAreaWithConsoleInput {

    public static void main(String[] args) {
        // Создаём объект Scanner
        Scanner input = new Scanner(System.in).useLocale(Locale.US);
        // Запрос пользователю на ввод радиуса
        System.out.print("Введите радиус: ");
        double radius = input.nextDouble();
        // Вычисление площади
        double area = radius * radius * 3.14159;
        // Отображение результата
        System.out.println("Площадь круга радиусом "
                + radius + " равна " + area);
    }
}

Проверь себя:

  1. Как вы пишите инструкцию, позволяющее пользователю ввести значение double с клавиатуры?
  2. Что произойдёт, если вы введёте 5a когда выполняется следующий код?
double radius = input.nextDouble();
  1. Имеется ли какая-либо разница в производительности между следующими двумя инструкциями импорта?
import java.util.Scanner;
import java.util.*;

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

wp-puzzle.com logo