Към съдържанието
wannacode

Вход и изход

Проблем

Програмата знае само едно име

Програмата поздравява клиента по име:

String name = "Мария";
System.out.println("Здравей, " + name + "!");
Изход
Здравей, Мария!

Работи, но поздравява всички като Мария. Името е записано в кода. За всеки нов клиент трябва да промениш програмата и да я пуснеш наново. Искаш програмата сама да попита.

Идеята

Четене от клавиатурата

Когато програмата чете, тя спира и чака. Човекът пише и натиска Enter. Написаното е входът на програмата.

Main.java
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 + " €");
Вход
12
30
Изход
Общо: 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 + " €");
Вход
12
30
Изход
Общо: 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 + " €");
Стъпка по стъпка, с думи
  1. Човекът пише 12 и Enter. nextLine() връща текста "12", не число.
  2. Integer.parseInt превръща текста в числото 12. То отива във first.
  3. 30 минава по същия път: текст, парсване, число в second.
  4. Сега + събира числа: 12 + 30 = 42.
  5. Отпечатва се „Общо: 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. Примерите в курса са с точка.

Пробвай

Колко билета?

Програмата чете колко са възрастните и колко са децата.

Вход
2
3

Какво ще отпечата програмата?

Scanner in = new Scanner(System.in);
int adults = Integer.parseInt(in.nextLine());
int children = Integer.parseInt(in.nextLine());
System.out.println("Билети: " + adults + children);
Отговор

Идеята

Числата, както ги искаш

В миналия урок цената 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);

Пробвай

Намери грешката

Програмата пита колко билета да запази. Тя не се компилира. На кой ред е грешката?

Избери реда с грешката.

Упражнение

Програми, които питат

Реши задачите в редактора си. Входът е по един ред за всяка стойност. Не печатай въпроси като „Въведи име:“, за да съвпадне изходът ти с примерния.

1. Поздрав по име. Прочети име и поздрави.

Вход
Мария
Изход
Здравей, Мария!

2. Сума на две числа. Прочети две цели числа и отпечатай сметката.

Вход
17
25
Изход
17 + 25 = 42

3. Два текста в един. Прочети два текста и ги отпечатай заедно, с интервал между тях.

Вход
Велико
Търново
Изход
Велико Търново

4. π с два знака. Запиши π в променлива като 3.14159265358979 и го отпечатай с два знака след точката. Готовата стойност Math.PI идва в следващия урок.

Изход
3.14

Още задачи

  • Възраст. Прочети име и възраст (цяло число) и отпечатай „Мария е на 19 години.“
  • Визитка от клавиатурата. Прочети име, професия и телефон и отпечатай визитката от урока „Първата програма“ с тях.
  • Цена с два знака. Прочети цена като дробно число и я отпечатай с два знака и знак за евро: при вход 7.5 изходът е Цена: 7.50 €.
  • Сума на две цени. Прочети две дробни цени и отпечатай сумата им с два знака: при вход 12.4 и 3.15 изходът е Общо: 15.55 €.

Тест

Провери се

1. Какво връща in.nextLine()?
2. Прочетени са текстовете "12" и "30". Какво дава first + second?
3. Какво прави Integer.parseInt("25")?
4. int a = 2; int b = 3; Какво отпечатва "Сума: " + a + b?
5. Как се отпечатва 7.5 като 7.50?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·