Глиф Учебники

Урок 3. Ввод и вывод

Курс «Java» · урок 3 из 10 · 4 минуты чтения

Программа, которая только печатает заранее известный текст, мало полезна. В этом уроке — как выводить данные красиво и как читать то, что набирает пользователь.

Вывод: print, println и printf

Java
public class Main {
    public static void main(String[] args) {
        System.out.print("Раз, ");
        System.out.print("два, ");
        System.out.println("три!");
        System.out.println();
        System.out.printf("%d + %d = %d%n", 2, 3, 2 + 3);
        System.out.printf("Имя: %s, возраст: %d%n", "Олег", 17);
        System.out.printf("[%5d]%n", 42);
    }
}
Вывод
Раз, два, три!

2 + 3 = 5
Имя: Олег, возраст: 17
[   42]
print и println System.out.print("Раз, "); System.out.print("два, "); System.out.println("три!"); Раз, два, три! дальше вывод пойдёт отсюда printf: шаблон и значения "Имя: %s, возраст: %d%n" перевод строки "Олег" 17 Имя: Олег, возраст: 17
print выводит текст и оставляет курсор на той же строке, println в конце переводит строку; printf подставляет значения "Олег" и 17 на места %s и %d по порядку, а %n переводит строку.

println() без значения выводит пустую строку. В шаблоне printf значения подставляются на места спецификаторов по порядку:

СпецификаторЧто подставляет
%dцелое число
%sстроку (или что угодно в виде текста)
%fдробное число, по умолчанию 6 знаков после запятой
%.2fдробное число с двумя знаками после запятой
%5dцелое число шириной 5 знаков, с пробелами слева
%nперевод строки

printf сам строку не переводит — нужен %n в конце. Тот же шаблон без вывода на экран даёт String.format: String s = String.format("%d шт.", 5);.

Дробные числа printf выводит по региональным настройкам системы. При русских настройках System.out.printf("%.2f", 3.14159) напечатает 3,14 с запятой, при английских — 3.14 с точкой. Если нужна точка всегда, укажите язык явно: System.out.printf(Locale.US, "%.2f%n", x) (и import java.util.Locale;). У println разделитель всегда точка.

Ввод: класс Scanner

Для чтения с клавиатуры служит класс Scanner. Он лежит в пакете java.util, поэтому в начале файла, до public class, нужна строка импорта:

Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("Как вас зовут?");
        String name = in.nextLine();
        System.out.println("Сколько вам лет?");
        int age = in.nextInt();
        System.out.println("Привет, " + name + "! Через год вам будет " + (age + 1) + ".");
    }
}
Ввод
Анна
16
Вывод
Как вас зовут?
Сколько вам лет?
Привет, Анна! Через год вам будет 17.

new Scanner(System.in) создаёт «читателя» стандартного ввода — клавиатуры. Создайте его один раз в начале программы и читайте через него всё. Без строки import компилятор выдаст cannot find symbol на слове Scanner. Можно импортировать и весь пакет сразу: import java.util.*;.

Основные методы Scanner:

МетодЧто читает
nextInt()целое число (int)
nextLong()большое целое число (long)
nextDouble()дробное число
next()одно слово — до пробела или конца строки
nextLine()всю строку до конца, с пробелами
nextBoolean()true или false
hasNextInt()проверяет, что дальше целое число, ничего не читая

nextInt(), nextDouble() и next() пропускают пробелы и переводы строк, поэтому числа можно вводить и через пробел, и каждое с новой строки:

Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int a = in.nextInt();
        int b = in.nextInt();
        int c = in.nextInt();
        System.out.println("Сумма: " + (a + b + c));
        System.out.println("Среднее: " + (a + b + c) / 3.0);
    }
}
Ввод
4 5
6
Вывод
Сумма: 15
Среднее: 5.0
ввод System.in 4 5 6 не прочитан 1 2 3 1 int a = in.nextInt(); сразу число a = 4 2 int b = in.nextInt(); пропускает пробел b = 5 3 int c = in.nextInt(); пропускает перевод строки c = 6
Ввод «4 5», Enter, «6», Enter: каждый nextInt() пропускает пробел или перевод строки перед числом и берёт 4, 5 и 6, а последний перевод строки остаётся непрочитанным.

Три ловушки Scanner

1. nextLine после nextInt возвращает пустую строку. nextInt() читает число и останавливается перед переводом строки. Следующий nextLine() видит этот перевод строки и сразу возвращает пустую строку. Как это исправить — в справке Scanner пропускает nextLine.

ввод System.in 16 Иван Петров не прочитано 1 2 1 int age = in.nextInt(); до перевода строки age = 16 2 String name = in.nextLine(); остаток строки — пусто name = ""
nextInt() забирает 16 и останавливается перед переводом строки, следующий nextLine() дочитывает эту строку и возвращает пустую, а «Иван Петров» остаётся непрочитанным.

2. nextDouble ждёт запятую. Scanner читает дробные числа по региональным настройкам системы. При русских настройках он ждёт 2,5, а на 2.5 останавливает программу с ошибкой InputMismatchException. Чтобы дробная часть всегда отделялась точкой, задайте язык:

Java
import java.util.Locale;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        in.useLocale(Locale.US);
        double price = in.nextDouble();
        int count = in.nextInt();
        System.out.println(price * count);
    }
}
Ввод
2.5 4
Вывод
10.0

3. Ввели не то. Если nextInt() встречает буквы, программа останавливается с ошибкой java.util.InputMismatchException. Проверить ввод заранее помогает hasNextInt() (условия — тема следующего урока), а перехватить ошибку — try и catch, о них справка Исключения: try и catch.

Русские буквы, набранные в командной строке Windows, программа может прочитать как непонятные значки: кодировка окна консоли не совпадает с той, что ждёт Java. В консоли IntelliJ IDEA такого обычно нет — запускайте примеры с русским вводом там.

Ввод и вывод на олимпиадах и в проверяющих системах

В заданиях с автоматической проверкой программа читает данные из стандартного ввода и пишет ответ в стандартный вывод, как в примерах выше. Лишних приглашений вроде «Введите число» выводить не нужно: проверяющая система сравнивает вывод с ответом посимвольно, и лишний текст считается ошибкой. Класс часто должен называться Main — смотрите правила конкретной системы.

Коротко

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

1. Что выведет System.out.print("A"); System.out.println("B"); System.out.print("C");?
2. Зачем в программе строка import java.util.Scanner;?
3. Какой метод прочитает строку «Иван Петров» целиком?
4. Программа читает nextDouble(), пользователь с русскими региональными настройками ввёл 2.5, и программа упала. Почему?