Вход и изход
Проблем
Програмата знае само едно име
Програмата поздравява клиента по име:
String name = "Мария";System.out.println("Здравей, " + name + "!");Здравей, Мария!Работи, но поздравява всички като Мария. Името е записано в кода. За всеки нов клиент трябва да промениш програмата и да я пуснеш наново. Искаш програмата сама да попита.
Идеята
Четене от клавиатурата
Когато програмата чете, тя спира и чака. Човекът пише и натиска Enter. Написаното е входът на програмата.
import java.util.Scanner;
public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.print("Как се казваш? "); String name = in.nextLine(); System.out.println("Здравей, " + name + "!"); }}МарияКак се казваш? Здравей, Мария!В Java за четене има помощник: Scanner. Редът import java.util.Scanner; най-отгоре казва откъде идва. Scanner in = new Scanner(System.in); го създава и го свързва с клавиатурата (System.in). После in.nextLine() чете един ред, до Enter.
Scanner е обект, а new създава обект. Какво значат, ще разберем в модул „Класове и обекти“. Засега тези два реда са част от обвивката на всяка програма, която чете. По-нататък в уроците не показваме реда с import.
Входът и изходът тук са показани поотделно. В конзолата името ще се появи там, където го пишеш: след „Как се казваш? “. Затова въпросът е с print: отговорът да е на същия ред.
По-точно, за любопитните
- Един
Scannerстига за цялата програма. Създавай го веднъж, в началото.
Проблем
12 + 30 = 1230
Касиерът въвежда две плащания, 12 € и 30 €. Програмата трябва да покаже общата сума:
Scanner in = new Scanner(System.in);String first = in.nextLine();String second = in.nextLine();String total = first + second;System.out.println("Общо: " + total + " €");1230Общо: 1230 €Вместо 42 излезе 1230. Програмата не е сбъркала сметката. Тя изобщо не е смятала.
Идеята
От текст към число
Каквото и да напише човекът, nextLine() връща текст. „12“ и „30“ са два текста, а + между текстове ги слепва. За да смяташ, превърни текста в число:
Scanner in = new Scanner(System.in);int first = Integer.parseInt(in.nextLine());int second = Integer.parseInt(in.nextLine());int total = first + second;System.out.println("Общо: " + total + " €");1230Общо: 42 €Превръщането на текст в стойност от друг тип се казва парсване (parse).
Integer.parseInt(...)даваint.Double.parseDouble(...)даваdouble.- Същото има и за другите типове:
Long.parseLong,Boolean.parseBooleanи т.н.
Сумата тук е първата сметка в курса. Изваждане, умножение и деление идват в следващия урок.
Scanner in = new Scanner(System.in);int first = Integer.parseInt(in.nextLine());int second = Integer.parseInt(in.nextLine());int total = first + second;System.out.println("Общо: " + total + " €");Стъпка по стъпка, с думи
- Човекът пише 12 и Enter. nextLine() връща текста "12", не число.
- Integer.parseInt превръща текста в числото 12. То отива във first.
- 30 минава по същия път: текст, парсване, число в second.
- Сега + събира числа: 12 + 30 = 42.
- Отпечатва се „Общо: 42 €“.
Scanner може да прочете и направо число: in.nextInt() или in.nextDouble(). Тогава числата може да са и на един ред, разделени с интервал:
Scanner in = new Scanner(System.in);int first = in.nextInt();int second = in.nextInt();int total = first + second;System.out.println("Общо: " + total + " €");По-точно, за любопитните
- Ако текстът не е число (например „дванайсет“), програмата спира с грешка:
NumberFormatException. Как се хваща такава грешка, ще видим в модул „Грешки и изключения“.
- Капан:
nextInt()чете числото, но не и Enter след него. СледващиятnextLine()прочита остатъка от същия ред, тоест празен текст:
Scanner in = new Scanner(System.in);int age = in.nextInt();String name = in.nextLine();System.out.println("Име: [" + name + "]");19МарияИме: []Името е празно. Затова в курса четем редове с nextLine() и ги превръщаме с Integer.parseInt. Ако ползваш nextInt(), сложи един празен in.nextLine(); преди следващото четене на текст.
- Десетичният знак зависи от регионалните настройки на компютъра.
Double.parseDoubleиска винаги точка:3.5.in.nextDouble()обаче следва настройките и на компютър с български настройки иска запетая:3,5. Примерите в курса са с точка.
Пробвай
Колко билета?
Програмата чете колко са възрастните и колко са децата.
23Какво ще отпечата програмата?
Scanner in = new Scanner(System.in);int adults = Integer.parseInt(in.nextLine());int children = Integer.parseInt(in.nextLine());System.out.println("Билети: " + adults + children);"Билети: " + adults вече е текстът „Билети: 2“, а текст + 3 слепва 3 накрая. Със скоби първо се смята сумата: "Билети: " + (adults + children) дава „Билети: 5“.Идеята
Числата, както ги искаш
В миналия урок цената 49.90 излезе като 49.9. За цена искаш винаги два знака след десетичната точка. Това е форматиран изход:
String product = "Слушалки";double price = 49.9;int qty = 2;System.out.printf("%s: %.2f €%n", product, price);System.out.printf("%d бр. в количката%n", qty);String label = String.format("Цена: %.2f €", price);System.out.println(label);Слушалки: 49.90 €2 бр. в количкатаЦена: 49.90 €printf печата текст с места за стойности. Всяко място започва с %, а стойностите идват след текста, в същия ред:
%sе текст,%dе цяло число;%.2fе дробно число с точно 2 знака след точката;%nе нов ред (printfне минава на нов ред сам).
String.format прави същото, но не печата, а връща текста. Можеш да го запишеш в променлива.
Стойността в променливата не се променя. Форматът решава само как да изглежда, когато се печата.
По-точно, за любопитните
- Хилядите и подравняването в колони:
double total = 1234.5;System.out.printf("Общо: %,.2f €%n", total);System.out.printf("%-10s|%8.2f%n", "Кафе", 2.5);System.out.printf("%-10s|%8.2f%n", "Лаптоп", 1299.0);Общо: 1,234.50 €Кафе | 2.50Лаптоп | 1299.00, добавя разделител за хилядите. Числото между % и буквата е ширината: %8.2f заема 8 знака, подравнено вдясно, а %-10s заема 10, подравнено вляво.
- И тук регионалните настройки имат значение. На компютър с български настройки
%.2fдава49,90, а разделителят за хилядите е интервал:1 234,50. Изходът в уроците е с точка.
Пробвай
Два знака
Нощувката струва 65.5 €. Искаш да излезе „Нощувка: 65.50 €“. Какво трябва да пише на празното място?
System.out.printf("Нощувка: €%n", price);%.2f: дробно число с точно два знака след точката.
Пробвай
Намери грешката
Програмата пита колко билета да запази. Тя не се компилира. На кой ред е грешката?
Избери реда с грешката.
in.nextLine() връща текст, а tickets е int. Компилаторът не превръща текст в число сам: „incompatible types: String cannot be converted to int“. Поправката е int tickets = Integer.parseInt(in.nextLine());.Упражнение
Програми, които питат
Реши задачите в редактора си. Входът е по един ред за всяка стойност. Не печатай въпроси като „Въведи име:“, за да съвпадне изходът ти с примерния.
1. Поздрав по име. Прочети име и поздрави.
МарияЗдравей, Мария!2. Сума на две числа. Прочети две цели числа и отпечатай сметката.
172517 + 25 = 423. Два текста в един. Прочети два текста и ги отпечатай заедно, с интервал между тях.
ВеликоТърновоВелико Търново4. π с два знака. Запиши π в променлива като 3.14159265358979 и го отпечатай с два знака след точката. Готовата стойност Math.PI идва в следващия урок.
3.14Още задачи
- Възраст. Прочети име и възраст (цяло число) и отпечатай „Мария е на 19 години.“
- Визитка от клавиатурата. Прочети име, професия и телефон и отпечатай визитката от урока „Първата програма“ с тях.
- Цена с два знака. Прочети цена като дробно число и я отпечатай с два знака и знак за евро: при вход
7.5изходът еЦена: 7.50 €. - Сума на две цени. Прочети две дробни цени и отпечатай сумата им с два знака: при вход
12.4и3.15изходът еОбщо: 15.55 €.
Тест