Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Czytanie wejścia tekstowego z klawiatury w JAVA

Ten wpis będzie takim małym oderwaniem od poradników dotyczących programowania aplikacji okienkowych, bo zajmiemy się czymś konsolowym. W Javie. A konkretniej czytaniem wejścia tekstowego z klawiatury — tak, jak to się robiło za starych czasów dominacji DOS-a lub teraz podczas używania terminala na jakimś Uniksoidzie (GNU/Linux, BSD, Solaris, OS X, AIX, HP-UX).

Co trzeba umieć?

  • Podstawy Java

Pobieramy tekst

Na początku głównej klasy programu (najprostsze założenie to program składając y się z jednej klasy) dorzucimy linijkę import java.util.Scanner;

Dzięki temu, użyjemy następujących dwóch linijek do pobrania tekstu z klawiatury: Scanner input = new Scanner(System.in); String text = input.nextLine();

Tym sposobem pobierzemy sobie linijkę tekstu od użytkownika: utworzymy obiekt klasy Scanner, który będzie przechwytywać systemowe wejście (z klawiatury). Następnie utworzymy zmienną typu String przechowującą pobraną z klawiatury linijkę. I na tym polega całe przechwytywanie tekstu.

Pobieramy liczby

Przez zamianę tekstu na liczbę

Pobieranie liczb polega na przechwyceniu tekstu i próby zamiany na liczbę. Wykorzystamy wcześniej omówione przechwytywanie tekstu.

Do zamiany tekstu na liczbę użyjemy int liczba = Integer.parseInt(String tekst); //dla typów Long, Float i Double wstaw właściwą nazwę i typ }

Polega to na tym, że próbujemy zamienić zmienną tekst na liczbę odpowiedniego typu. Jeśli się uda ta zamiana, mamy liczbę. Jeśli nie, zostanie zgłoszony wyjątek NumberFormatException. Aby zabezpieczyć się przed takim wyjątkiem, przechwytywanie liczb zrobimy tak: [int,long,float,double] liczba=0; try { int liczba = Integer.parseInt(String tekst); //dla typów Long, Float i Double wstaw właściwą nazwę i typ } catch(NumberFormatException e) { System.out.println("Tu nie ma liczby :["); }

Bezpośrednio z klawiatury

Zamiast input.nextLine() z sekcji powyżej zastosujemy nextInt()/nextLong()/nextFloat()/nextDouble() zgodnie z poniższym szablonem:int liczba = input.next[Int,Long,Float,Double]();. Aby zabezpieczyć się przed wyjątkiem InputMismatchException, zmienimy nazwę wyjątku w catch(NumberFormatException) na InputMismatchException, co ma wyglądać tak: [int,long,float,double] liczba=0; try { int liczba = input.nextInt(); //dla typów Long, Float i Double wstaw właściwą nazwę i typ } catch(InputMismatchException e) { System.out.println("Tu nie ma liczby :["); }

Bardzo podobnie postępujemy z innymi typami liczbowymi, tzn. BigInteger, Short, Byte, BigDecimal.

Przechwytujemy wartości logiczne

Tak samo jak tekst czy liczby, możemy pobierać wartości logiczne (typ boolean). Wykonuje się to tak, jak z liczbami, ale to wygląda tak:boolean zmienna = input.nextBoolean();

Wraz z obsługą wyjątku: try { boolean zmienna = input.nextBoolean(); } catch(InputMismatchException e) { System.out.println("Houston, we've had a problem."); }

Podsumowanie

Dzięki temu wpisowi zapoznamy się/nauczymy się przechwytywać od użytkownika dane ze standardowego wejścia i sprawdzać, czy są one poprawne. Do tego nie zapomnijmy o imporcie pakietów z wyjątkami, gdyż przedstawione przykłady nie będą działać. 

porady programowanie

Komentarze

0 nowych
Druedain   14 #1 26.06.2012 13:33

To jest straszne, że tak proste rzeczy wymagają w Javie tyle zachodu. Takie rzeczy najlepiej jest napisać dobrze raz, wpakować do biblioteki i zapomnieć o tym co jest pod spodem…

GL1zdA   12 #2 26.06.2012 13:38

@Druedain
Ale co jest w tym skomplikowanego? Wywołujesz jedną metodę i gotowe.

alucosoftware   7 #3 26.06.2012 14:22

Nie jestem specjalistą od Javy, ale uważam, że przedstawiony sposób jest "okropny" :)

Masz dwie zmienne: liczba1 oraz liczba2 zadeklarowane jak powyżej. Dokonujesz konwersji łańcucha tekstowego na jeden z "pasujących" typów prymitywnych. Na jaki? Jakiego typu jest wynik operacji matematycznych wykorzystujących te dwie zmienne?

Nie wiedząc z jakim typem masz do czynienia w dowolnym fragmencie programu, czy przed każdą operacją na zmiennej będziesz sprawdzał czy to int, long, float a może double?

budda86   9 #4 26.06.2012 15:32

@alucosoftware
Dokonujesz parsowania do takiego typu, jaki chcesz. Autor wpisu użył dość niefortunnego sposobu, żeby to zobrazować, pisząc "[int,long,float,double] liczba". Taki zapis sugeruje, że nie wiadomo, jakiego typu jest zmienna liczba. Ale to nie jest poprawny kod, tylko sposób pokazania możliwych alternatyw; w kodzie musisz jednoznacznie okreslić typ zmiennej.

Moim zdaniem sposób, w jaki autor wpisu to pokazał, jest bardzo zły. Zastosował kolorowanie składni do tego "zbioru alternatyw" i wymieszał z poprawnym kodem, co moim zdaniem utrudnia zrozumienie tematu i wprowadza niepotrzebny zamęt.

flaszer   10 #5 26.06.2012 16:03

No niestety. Kolejny wpis o programowaniu w JAVA i kolejny raz czuję rozczarowanie.


@Druedain
Co konkretnie wymaga tyle zachodu? Toż to zwykłe bloki try/catch.

iluzion   5 #6 26.06.2012 17:14

Druedain ma rację.

"Na początku głównej klasy programu (najprostsze założenie to program składając y się z jednej klasy)"

Do czego jest tu klasa potrzebna? (wiem, wiem...). Szczytem byłoby rozwiązanie tego problemu z pomocą kilku klas.

Dla odmiany nieco inne podejście w Pythonie:

http://dpaste.com/hold/763765/
http://i.imgur.com/HJUW9.png

iluzion   5 #7 26.06.2012 17:27

Ps Oczywiście wprowadzenie czegoś takiego jak 123.a czy abc.1 zakończy się wyjątkiem ValueError ;)

GL1zdA   12 #8 26.06.2012 17:50

@iluzion
Gdyby to naprawdę miało znaczenie, to przez 20 lat istnienia Javy już dawno ktoś by dodał opcję "ukrycia" tych 2 linijek potrzebnych na stworzenie klasy. Jak się piszę jednak coś więcej niż tutoriale, to zaczyna się doceniać sztywność Javy i fakt, że na takie rzeczy nie pozwala.

iluzion   5 #9 26.06.2012 18:10

@GL1zdA

Rzecz gustu. Niektórzy wolą być ograniczani, żeby nie zrobić sobie krzywdy, inni wolą więcej swobody.

"przez 20 lat istnienia Javy już dawno ktoś by dodał opcję "ukrycia" tych 2 linijek potrzebnych na stworzenie klasy"

... i to się właśnie dzieje. Współczesne języki jak np. Go czy Clojure (możliwe, że Scala również) umożliwiają pisanie programów bez użycia klas (ba, w Go nawet nie ma klas), w Clojure z tego co wiem mamy ns (namespace) i te dwie litery całkowicie wystarczają do zastąpienia deklaracji klasy z metodą public static void main(String args[]){ } .

Przestrzenie nazw praktycznie zawsze służą czytelności itd., klasy już nie zawsze są potrzebne. W opisanym tutaj przypadku zdecydowanie są czymś zbędnym.

Polecam:

Stop Writing Classes: http://pyvideo.org/video/880/stop-writing-classes

Typical C++ bullshit: http://macton.smugmug.com/gallery/8936708_T6zQX/1/593426709_ZX4pZ#!i=593426709&a...

iluzion   5 #10 26.06.2012 18:27

Ps Jeszcze raz nawiążę do tego zdania:

"przez 20 lat istnienia Javy już dawno ktoś by dodał opcję "ukrycia" tych 2 linijek potrzebnych na stworzenie klasy"

Od 20 lat programiści czekają na dodanie lambdy, więc jak można wymagać usunięcia czegoś z języka, od którego wymaga się tak dużej kompatybilności wstecznej? Ta kompatybilność jest teraz jedną z największych zalet Javy -- Cobola XXI wieku.

Warto zwrócić też uwagę na najnowszy film promujący Javę:

http://jz12.java.no/videos

Dla mnie przekaz tego filmu jest jasny. JVM to dojrzała, wydajna maszyna wirtualna, platforma dla WIELU języków programowania. JVM jest bohaterem tego filmu. Nie Java jako język.

GL1zdA   12 #11 26.06.2012 18:44

@iluzjon
"Niektórzy wolą być ograniczani, żeby nie zrobić sobie krzywdy, inni wolą więcej swobody."
Jeśli piszesz sam - OK, jeśli piszesz zespołowo, to takie myślenie do niczego nie prowadzi.

"... i to się właśnie dzieje. Współczesne języki jak np. Go czy Clojure (możliwe, że Scala również) umożliwiają pisanie programów bez użycia klas (ba, w Go nawet nie ma klas), w Clojure z tego co wiem mamy ns (namespace) i te dwie litery całkowicie wystarczają do zastąpienia deklaracji klasy z metodą public static void main(String args[]){ } ."
Problem w tym, że w tych językach się nie pisze:
http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
I uwierz mi, nie wynika to z tego, że ludzie nie dostrzegają ich wspaniałości.

"Przestrzenie nazw praktycznie zawsze służą czytelności itd., klasy już nie zawsze są potrzebne. W opisanym tutaj przypadku zdecydowanie są czymś zbędnym. "
Tylko poza tutorialami, nie pisze się programów zamykającymi się w 3 linijkach. A klasy już przy kilkuset linijkach zaczynają przynosić korzyści. Też kiedyś miałem program, który zaczynał od skryptu w bashu, przeszedł przez Perl i skończył w Javie - bo po przekroczeniu 500 linijek tak było łatwiej go pielęgnować.

"Stop Writing Classes: http://pyvideo.org/video/880/stop-writing-classes"
Mam za słabe łącze na filmy

"Typical C++ bullshit: http://macton.smugmug.com/gallery/8936708_T6zQX/1/593426709_ZX4pZ#!i=593426709&a......:"
W każdym języku da się pisać zły kod, a to co pokazują to błędy projektowe a nie błędy wynikające z ułomności języka.

GL1zdA   12 #12 26.06.2012 18:50

@iluzjon
"Od 20 lat programiści czekają na dodanie lambdy"
Nie spałeś zapewne pod kamieniem ostatnie pięć lat, więc zdajesz sobie zapewne sprawę z tego, że w między czasie Oracle przejmował Sun i dodawania lambd nie było priorytetem. Za to jak zostaną dodane, będę miał pewność, że nie będzie to przypięty byle jak fragment składni, tylko przemyślana część języka.

"JVM to dojrzała, wydajna maszyna wirtualna, platforma dla WIELU języków programowania."
Zgadza się, tylko ludzie będą z nich korzystać, gdy osiągną dojrzałość Javy (chociażby ze względu na narzędzia). Ewolucja C -> C++ -> Java/C# przedstawia określony kierunek, który moim zdaniem jeszcze długo się nie zmieni.

iluzion   5 #13 26.06.2012 19:32

@GL1zdA

Ranking TIOBE pokazuje tylko przybliżony trend obarczony sporymi błędami. No ale jednak pewne tendencje obrazuje:

http://www.tiobe.com/index.php/paperinfo/tpci/Java.html

To, że się w jakimś języku nie pisze nie oznacza, że nie da się w nim realizować projektów większych niż tutoriale. Oczywistą sprawą jest, że zmiany dokonują się długimi latami. Wiele z tych języków nie przetrwa próby czasu, ale te dwa wymienione powyżej języki na JVM mają ułatwione zadanie. Biblioteki, narzędzia, możliwość uruchamiana na różnych platformach bez dodatkowego wysiłku ze strony programistów itd. itp. Tego nie miały inne języki i się nie przyjęły.

Historia pokazuje jeszcze jedną prawidłowość. Nie przyjmują się "czyste" języki, np. Smalltalk (czysto obiektowy), Haskell (czysto funkcyjny). One ładnie wyglądają w publikacjach naukowych i na blogach, w "życiu" nieco gorzej.

"Tylko poza tutorialami, nie pisze się programów zamykającymi się w 3 linijkach."

Ależ pisze się;) Polecam spojrzeć na implementację wbudowanych funkcji w Clojure i porównać je z implementacjami odpowiedników w innych językach programowania, np. funkcji z modułu itertools Pythona:

http://clojuredocs.org/clojure_core/clojure.core
http://docs.python.org/py3k/library/itertools.html?highlight=itertools#itertools

Przykładowa funkcja: groupby

http://cljbin.com/paste/4fe9eca2e4b0aacc1b2a87e7
http://dpaste.com/hold/763839/

Nie odważę się potwierdzić tezę, że kod takich funkcji jak pmap (parallel map) to nic nie znaczący, błachy przykład, bo składa się tylko z kilkunastu krótkich linii.

"A klasy już przy kilkuset linijkach zaczynają przynosić korzyści."

Korzyści? Jeśli kod Twojej funkcji / klasy ma więcej niż 100 linii, to wiedz, że coś się dzieje! Jeśli Twój kod jest zagnieżdżony tak daleko, że musisz używać poziomego suwaka w IDE, to wiedz, że diabeł się nim interesuje! :)

Na koniec dwa przykłady:

1. Funkcja sprawdzająca czy słowo składa się z pustych znaków:

Java:

http://pastebin.com/Usqirgzt

Clojure:

http://pastebin.com/CCs36KGj

2. Klasa Person, czyli "nic nie robiące" linie kodu:

Java:

http://pastebin.com/836e26SE

Clojure:

http://pastebin.com/uhLkN5ty

  #14 26.06.2012 20:36

"W każdym języku da się pisać zły kod, a to co pokazują to błędy projektowe a nie błędy wynikające z ułomności języka."

Każdy człowiek może napisać równie mało znaczące zdanie.

Sedno problemu polega na tym, że piszesz kod dla komputera i to on ma go interpretować i rozumieć możliwie wydajnie. A nie ubierać w kwiatki wyglądające ładnie na kartce i dla kolegów z biura.

GL1zdA   12 #15 26.06.2012 23:13

@sprae
"Każdy człowiek może napisać równie mało znaczące zdanie. "
Coż było mało znaczącego w tym zdaniu?

"Sedno problemu polega na tym, że piszesz kod dla komputera i to on ma go interpretować i rozumieć możliwie wydajnie."
I co to ma wspólnego ze zwięzłością języka programowania?

@iluzion
"No ale jednak pewne tendencje obrazuje: "
Ale patrz jakie języki idą w górę - C# i Objective-C. Nie są to najbardziej zwięzłe języki jakie widziałem.

"A klasy już przy kilkuset linijkach zaczynają przynosić korzyści." "
Chodziło oczywiście o długość programu, nie funkcji czy klasy.

"Tylko poza tutorialami, nie pisze się programów zamykającymi się w 3 linijkach."
"Ależ pisze się;)"
j.w. - nie zrozumieliśmy się, ale to bez znaczenia.

"1. Funkcja sprawdzająca czy słowo składa się z pustych znaków"
OK, pokazuje to dwie możliwości składni, których w Javie nie ma. W Javie 8 pewnie da się to zamknąć 2-3 linijkach, jeśli już ścigamy się na krótkość. Czy to

"2. Klasa Person, czyli "nic nie robiące" linie kodu: "
Są biblioteki do Javy, które działają podobnie jak defrecord, ale jakoś świata nie podbiły.

Co do dlugości przykładów - najlepszym komentarzem niech będzie biblioteka idiomów APLa - FinnAPL:
http://aplwiki.com/FinnAplIdiomLibrary
Przepisz to teraz w Clojure nie przekraczając dwukrotnej długości ;)

zeyomir   4 #16 26.06.2012 23:40

@sprae
"Sedno problemu polega na tym, że piszesz kod dla komputera i to on ma go interpretować i rozumieć możliwie wydajnie. A nie ubierać w kwiatki wyglądające ładnie na kartce i dla kolegów z biura."

Sedno problemu to polega na tym, że kod pisze się raz, a czyta setki razy. Więc jak ktoś chce poświęcić czytelność i zrozumiałość kodu na rzecz 3 linijek mniej do napisania to jest to delikatnie mówiąc... krótkowzroczne i niemądre. Tyle odnośnie oceniania języka/paradygmatu na podstawie długości kodu.

@iluzion
Nic nie zaciemnia obrazu lepiej, niż dobrze dobrany przykład ;). Skoro ma być krótko:
ad 1.
boolean isBlank(String testowy){
return testowy.replaceAll("\\s+","").length() > 0 ? false : true;
}

ad 2.
public class Person{
public String firstName, lastName; //tak, Twój kod tylko udaje, że robi coś więcej..
}

Nie chcę się tutaj sprzeczać na temat wyższości jednego języka nad drugim- zakończę więc pewnym cytatem:
"Języki programowania dzielą się na takie, na które ciągle ktoś narzeka i na takie, których nikt nie używa".

iluzion   5 #17 27.06.2012 00:56

@GL1zdA

"Ale patrz jakie języki idą w górę - C# i Objective-C. Nie są to najbardziej zwięzłe języki jakie widziałem."

Microsoft i Apple ciągną te języki w górę rankingów. Objective-C jest podstawowym (nadal jedynym?) językiem dla iOS. C# jest aktualnie podstawowym językiem dla Windows, jeśli się nie mylę jest też najlepiej udokumentowany. Jak mówi stare polskie porzekadło... "nie chcem, ale muszem".

"Chodziło oczywiście o długość programu, nie funkcji czy klasy."

Przy dobrze przemyślanej strukturze programu jego długość ma mniejsze znaczenie. Szczególnie w językach takich jak wspomniany Clojure, gdzie struktury danych są niezmienne, nie ma "lock-ów" i innych zmian stanu. Im mniej pułapek tym lepiej.

"Są biblioteki do Javy, które działają podobnie jak defrecord, ale jakoś świata nie podbiły."

Bo to "obce" twory. Zwiększają liczbę zależności, mogą negatywnie wpływać na kompatybilność czy przenośność (chociaż w Javie to raczej rzadki problem) itd.

Do listy języków, które szybko zyskują na popularności można jeszcze dodać JavaScript -- język, który uchodzi za jeden z największą liczbą pułapek ;)

GL1zdA   12 #18 27.06.2012 08:04

@iluzion
"Do listy języków, które szybko zyskują na popularności można jeszcze dodać JavaScript -- język, który uchodzi za jeden z największą liczbą pułapek ;)"
Bo wszystkim się wydaje, że potrafią pisać w JS nie ucząc się go i piszą w JS jakby pisali w Javie. A wystarczy przeczytać http://helion.pl/ksiazki/javascript-mocne-strony-douglas-crockford,jscmoc.htm i przejrzeć http://javascript.crockford.com/ by zrozumieć ten język i pisać w nim dobre programy.

Druedain   14 #19 27.06.2012 16:36

„Za to jak zostaną dodane, będę miał pewność, że nie będzie to przypięty byle jak fragment składni, tylko przemyślana część języka.” ja pewności nie mam, biorąc pod uwagę słynną funkcję daty, która dni i lata indeksowała od 1, ale miesiąc od 0.

Generalnie rzecz biorąc, chyba nie włączę w dyskusję, bo póki co wiedza nie ta i doświadczenie nie to. A do czego ja się konkretnie przyczepiłem na początku było związane z tym, że kiedy np. w takim C# po prostu się używa wejścia, w Javie trzeba się bawić najpierw w jego interpretację. Po co to komu? Przyjmuję do wiadomości, że problemem może być marudzenie wynikające z braku wiedzy. Dlatego jestem otwarty na krytykę mojego toku myślenia.

Co do wojny o lepszy paradygmat, niestety dla mnie to na razie pozostaje dyskusją akademicką, gdyż nawet jakbym chciał i bym miał wiedzę, nie miałbym możliwości wykorzystania wiedzy na temat programowania funkcyjnego w praktyce.

Autor edytował komentarz.
revcorey   7 #20 27.06.2012 19:14

Wiecie ja tam jestem samoukiem. I powiem tyle java jest ok ale używając niektórych klas w javie itp. Rozumiem jakie zamierzenie mieli twórcy tylko że im to nie wyszło. Trzeba było gdzie niegdzie kodu nadłożyć żeby coś tam zrobić.

Yuri20   5 #21 27.06.2012 22:38

Chcieli dobrze, ale wyszło jak zawsze :<

GL1zdA   12 #22 28.06.2012 09:11

@Druedain
Date jest czymś co się ciągnie od JDK 1.0, jeśli chcesz czegoś lepszego to jest Joda Time.
Co do C# to nie bardzo wiem co znaczy "po prostu używa się wejścia". Czytanie liczb w C# wygląda bardzo podobnie do czytania ich w Javie:
http://www.functionx.com/csharp2/fundamentals/Lesson05.htm