Урок 3. Ввод и вывод
Программа, которая только печатает заранее известный текст, мало полезна. В этом уроке — как выводить данные красиво и как читать то, что набирает пользователь.
Вывод: print, println и printf
System.out.println(x)— выводит значение и переводит строку.System.out.print(x)— выводит значение и остаётся на той же строке.System.out.printf(шаблон, значения)— выводит по шаблону.
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]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, нужна строка импорта:
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() пропускают пробелы и переводы строк, поэтому числа можно вводить и через пробел, и каждое с новой строки:
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Три ловушки Scanner
1. nextLine после nextInt возвращает пустую строку. nextInt() читает число и останавливается перед переводом строки. Следующий nextLine() видит этот перевод строки и сразу возвращает пустую строку. Как это исправить — в справке Scanner пропускает nextLine.
2. nextDouble ждёт запятую. Scanner читает дробные числа по региональным настройкам системы. При русских настройках он ждёт 2,5, а на 2.5 останавливает программу с ошибкой InputMismatchException. Чтобы дробная часть всегда отделялась точкой, задайте язык:
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 410.03. Ввели не то. Если nextInt() встречает буквы, программа останавливается с ошибкой java.util.InputMismatchException. Проверить ввод заранее помогает hasNextInt() (условия — тема следующего урока), а перехватить ошибку — try и catch, о них справка Исключения: try и catch.
Русские буквы, набранные в командной строке Windows, программа может прочитать как непонятные значки: кодировка окна консоли не совпадает с той, что ждёт Java. В консоли IntelliJ IDEA такого обычно нет — запускайте примеры с русским вводом там.
Ввод и вывод на олимпиадах и в проверяющих системах
В заданиях с автоматической проверкой программа читает данные из стандартного ввода и пишет ответ в стандартный вывод, как в примерах выше. Лишних приглашений вроде «Введите число» выводить не нужно: проверяющая система сравнивает вывод с ответом посимвольно, и лишний текст считается ошибкой. Класс часто должен называться Main — смотрите правила конкретной системы.
Коротко
printlnпереводит строку,print— нет,printfвыводит по шаблону:%d,%s,%.2f,%n.Scannerподключается строкойimport java.util.Scanner;и создаётся один раз:new Scanner(System.in).nextInt,nextDouble,nextчитают одно значение,nextLine— всю строку.- После
nextIntпервыйnextLineвернёт пустую строку — остаток строки с числом. - Дробные числа в
printfиnextDoubleзависят от языка системы;Locale.USделает разделителем точку.