College Compass

College Compass

Software Development · CN4001

Εβδομάδα 4: Είσοδος από τον χρήστη με τον Scanner

  • java
  • scanner
  • input-validation
  • locale

Σημειώσεις μελέτης βασισμένες στο «Learn Programming with Java – Scanner». Οι διαφάνειες, με τα 13 παραδείγματα και τις ασκήσεις τους, βρίσκονται στο Moodle.

Ως τώρα οι τιμές ήταν «καρφωμένες» μέσα στον κώδικα. Για να ρωτά το πρόγραμμα τον χρήστη, η Java έχει την κλάση Scanner, που διαβάζει ό,τι πληκτρολογεί κάποιος στην κονσόλα.

Το βασικό σχήμα

import java.util.Scanner;

public class Greeting {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        System.out.print("Πώς σε λένε; ");
        String name = input.nextLine();

        System.out.println("Γεια σου, " + name + "!");
        input.close();
    }
}
  • Το import java.util.Scanner; φέρνει την κλάση στο πρόγραμμα.
  • Το new Scanner(System.in) φτιάχνει έναν Scanner που διαβάζει από το πληκτρολόγιο. Αρκεί ένας για όλο το πρόγραμμα.
  • Το input.close() τον κλείνει στο τέλος.

Ποια μέθοδος για τι

Μέθοδος Διαβάζει Παράδειγμα εισόδου → τιμή
nextLine() όλη τη γραμμή, με τα κενά Οδός Ακαδημίας 10 → "Οδός Ακαδημίας 10"
next() την επόμενη «λέξη», ως το πρώτο κενό Harry Potter → "Harry"
nextInt() έναν ακέραιο 25 → 25
nextDouble() έναν δεκαδικό 19,99 ή 19.99 (βλ. παρακάτω)
nextBoolean() true ή false true → true

Η παγίδα του nextLine. Το nextInt() διαβάζει τον αριθμό αλλά αφήνει το Enter στην είσοδο. Αν μετά καλέσεις nextLine(), θα διαβάσει αυτό το κενό υπόλοιπο και θα επιστρέψει αμέσως "". Η λύση: ένα επιπλέον nextLine() για να «καταναλώσει» το Enter.

int age = input.nextInt();
input.nextLine();                 // πετάει το Enter που περίσσεψε
String address = input.nextLine();

Για να καθαρίσεις κενά στην αρχή και στο τέλος του κειμένου, χρησιμοποίησε trim()· για σύγκριση χωρίς διάκριση κεφαλαίων, equalsIgnoreCase():

String colour = input.nextLine().trim();   // "  Blue " → "Blue"
if (colour.equalsIgnoreCase("blue")) {
    System.out.println("Ήρεμο χρώμα.");
}

Έλεγχος εισόδου

Αν ζητήσεις nextInt() και ο χρήστης γράψει «είκοσι», το πρόγραμμα σταματά με InputMismatchException. Για να το αποφύγεις, ρωτάς πρώτα αν η επόμενη τιμή είναι του σωστού τύπου, με τις μεθόδους hasNextInt(), hasNextDouble() κ.λπ.:

System.out.print("Πόσα τεμάχια θέλεις; ");

if (input.hasNextInt()) {
    int quantity = input.nextInt();
    if (quantity > 0) {
        System.out.println("Παρήγγειλες " + quantity + " τεμάχια.");
    } else {
        System.out.println("Η ποσότητα πρέπει να είναι θετική.");
    }
} else {
    System.out.println("Δώσε αριθμό, όχι κείμενο.");
}

Για να ζητάς ξανά μέχρι να πάρεις έγκυρη τιμή, βάζεις τον έλεγχο σε έναν βρόχο while:

int number;
while (true) {
    System.out.print("Δώσε αριθμό από 1 έως 10: ");
    if (input.hasNextInt()) {
        number = input.nextInt();
        if (number >= 1 && number <= 10) break;   // έγκυρη τιμή: βγαίνουμε
        System.out.println("Εκτός ορίων.");
    } else {
        System.out.println("Αυτό δεν είναι αριθμός.");
        input.next();                              // πετάμε τη λάθος είσοδο
    }
}

Χωρίς το input.next() στο else, η λάθος λέξη θα έμενε στην είσοδο και ο βρόχος θα έτρεχε για πάντα.

Δεκαδικοί και Locale

Ο Scanner διαβάζει τους δεκαδικούς με βάση τις τοπικές ρυθμίσεις (locale) του υπολογιστή. Σε έναν υπολογιστή με ελληνικές ρυθμίσεις, το διαχωριστικό είναι το κόμμα (19,99)· σε αγγλικές ΗΠΑ, η τελεία (19.99). Αν ο χρήστης χρησιμοποιήσει το άλλο, η είσοδος θεωρείται άκυρη.

Για να δουλεύει το πρόγραμμα ίδια παντού, ορίζεις ρητά το locale:

import java.util.Locale;

Scanner usInput = new Scanner(System.in).useLocale(Locale.US);       // 19.99
Scanner grInput = new Scanner(System.in).useLocale(Locale.of("el", "GR")); // 19,99

Το Locale.of υπάρχει από τη Java 19· σε παλιότερες εκδόσεις γράφεις new Locale("el", "GR").

Πολλές τιμές σε μία γραμμή

Ο Scanner χωρίζει την είσοδο σε κομμάτια (tokens) με βάση τα κενά. Έτσι, ο χρήστης μπορεί να γράψει τρεις αριθμούς στην ίδια γραμμή:

System.out.print("Δώσε τρεις αριθμούς: ");   // π.χ. 4 7 9
int a = input.nextInt();
int b = input.nextInt();
int c = input.nextInt();
System.out.println("Άθροισμα: " + (a + b + c));   // Άθροισμα: 20

Αν θέλεις άλλο διαχωριστικό, π.χ. κόμματα (4,7,9), το ορίζεις με useDelimiter:

Scanner csv = new Scanner(System.in).useDelimiter("[,\\s]+");

Η έκφραση [,\\s]+ σημαίνει «ένα ή περισσότερα κόμματα ή κενά», ώστε να λειτουργεί και το Enter στο τέλος της γραμμής.

Τέλος, το skip() προσπερνά ένα συγκεκριμένο κομμάτι κειμένου. Αν κάθε γραμμή ξεκινά με μια ετικέτα, π.χ. Όνομα: Άννα, το input.skip("Όνομα: ") την προσπερνά και το nextLine() διαβάζει μόνο την τιμή.

Ερωτήσεις αυτοαξιολόγησης

1. Ο χρήστης γράφει «Άννα Παππά». Τι επιστρέφει το next() και τι το nextLine();

Το next() επιστρέφει «Άννα» (ως το πρώτο κενό). Το nextLine() επιστρέφει όλη τη γραμμή, «Άννα Παππά».

2. Γιατί το πρόγραμμα παραλείπει την ερώτηση για τη διεύθυνση μετά από ένα nextInt();

Γιατί το nextInt() αφήνει το Enter στην είσοδο, και το επόμενο nextLine() το διαβάζει αμέσως ως κενή γραμμή. Ένα επιπλέον nextLine() μετά το nextInt() λύνει το πρόβλημα.

3. Τι κάνει το hasNextInt() και γιατί είναι χρήσιμο;

Ελέγχει, χωρίς να «καταναλώσει» την είσοδο, αν η επόμενη τιμή είναι ακέραιος. Έτσι αποφεύγεις το InputMismatchException όταν ο χρήστης γράψει κείμενο.

4. Σε έναν υπολογιστή με ελληνικές ρυθμίσεις ο χρήστης γράφει 19.99 για nextDouble(). Τι γίνεται;

Η είσοδος θεωρείται άκυρη, γιατί με ελληνικό locale ο Scanner περιμένει κόμμα (19,99). Για να δέχεται τελεία, ορίζεις useLocale(Locale.US).


Πηγές: «Learn Programming with Java – Scanner» του μαθήματος· τεκμηρίωση της κλάσης Scanner.

Ασκήσεις της εβδομάδας

Άσκηση

4η Εβδομαδιαία Εργασία (Kosmidis)

Προθεσμία
Χωρίς προθεσμία — για εξάσκηση

13 προγράμματα με Scanner: γεωμετρία, μετατροπές μονάδων, ποσοστά, φόρος εισοδήματος και κλίμακες με if.

Εκφώνηση

Ερώτημα 1

Ζητήστε από τον χρήστη την ακτίνα και το ύψος ενός κυλίνδρου και υπολογίστε τον όγκο του.

Οδηγίες:

  1. Ζητήστε την ακτίνα και το ύψος του κυλίνδρου από τον χρήστη.
  2. Υπολογίστε τον όγκο με τον τύπο: V = π · radius² · height
  3. Εκτυπώστε το αποτέλεσμα.

Ερώτημα 2

Ζητήστε από τον χρήστη να εισάγει πέντε αριθμούς και υπολογίστε τη μέση τιμή τους.

Οδηγίες:

  1. Ζητήστε από τον χρήστη να εισάγει πέντε αριθμούς.
  2. Υπολογίστε τη μέση τιμή με τον τύπο: Average = sumofnumbers / 5
  3. Εκτυπώστε το αποτέλεσμα.

Ερώτημα 3

Ζητήστε από τον χρήστη να εισάγει μια θερμοκρασία σε Φαρενάιτ και μετατρέψτε την σε Κελσίου.

Οδηγίες:

  1. Ζητήστε τη θερμοκρασία σε Φαρενάιτ.
  2. Υπολογίστε τη θερμοκρασία σε Κελσίου με τον τύπο: C = (F − 32) · 5/9
  3. Εκτυπώστε το αποτέλεσμα.

Ερώτημα 4

Ζητήστε από τον χρήστη τη βάση και το ύψος ενός τριγώνου και υπολογίστε την έκτασή του.

Οδηγίες:

  1. Ζητήστε τη βάση και το ύψος του τριγώνου.
  2. Υπολογίστε την έκταση με τον τύπο: A = ½ · base · height
  3. Εκτυπώστε το αποτέλεσμα.

Ερώτημα 5

Ζητήστε από τον χρήστη να εισάγει χρόνο σε λεπτά και μετατρέψτε τον σε ώρες και λεπτά.

Οδηγίες:

  1. Ζητήστε χρόνο σε λεπτά.
  2. Υπολογίστε τις ώρες και τα υπόλοιπα λεπτά με τους τύπους:
    1. Ώρες: hours = minutes / 60
    2. Λεπτά: remainingminutes = minutes
  3. Εκτυπώστε το αποτέλεσμα.

Ερώτημα 6

Ζητήστε από τον χρήστη την απόσταση και την κατανάλωση καυσίμου του αυτοκινήτου (λίτρα ανά 100 χλμ) και υπολογίστε το συνολικό κόστος του ταξιδιού.

Οδηγίες:

  1. Ζητήστε την απόσταση και την κατανάλωση καυσίμου.
  2. Υπολογίστε την ποσότητα καυσίμου που απαιτείται και το συνολικό κόστος με τον τύπο: FuelNeeded = (distance · consumption) / 100
  3. Εκτυπώστε το κόστος.

Ερώτημα 7

Ζητήστε από τον χρήστη τον αρχικό πληθυσμό και το ποσοστό ετήσιας αύξησης και υπολογίστε τον πληθυσμό μετά από 5 χρόνια.

Οδηγίες:

  1. Ζητήστε τον αρχικό πληθυσμό και το ποσοστό αύξησης.
  2. Υπολογίστε τον πληθυσμό για κάθε έτος για 5 χρόνια με τον τύπο: PopulationYearN = PopulationYearN − 1 · (1 + growthrate)
  3. Εκτυπώστε τον τελικό πληθυσμό μετά από 5 χρόνια.

Ερώτημα 8

Ζητήστε από τον χρήστη να εισάγει έναν αριθμό και υπολογίστε την τετραγωνική ρίζα του.

Οδηγίες:

  1. Ζητήστε τον αριθμό.
  2. Υπολογίστε την τετραγωνική ρίζα με τον τύπο: SquareRoot = √number
  3. Εκτυπώστε το αποτέλεσμα.

Ερώτημα 9

Ζητήστε από τον χρήστη την τιμή ενός προϊόντος και το ποσοστό ΦΠΑ και υπολογίστε την τελική τιμή.

Οδηγίες:

  1. Ζητήστε την τιμή προϊόντος και το ποσοστό ΦΠΑ.
  2. Υπολογίστε την τελική τιμή με τον τύπο: FinalPrice = price · (1 + VAT/100)
  3. Εκτυπώστε το αποτέλεσμα.

Ερώτημα 10

Δημιουργήστε ένα πρόγραμμα που υπολογίζει τον φόρο εισοδήματος με βάση το ετήσιο εισόδημα. Οι φορολογικές κλίμακες είναι οι εξής:

  • Εισόδημα μέχρι €10,000: Χωρίς φόρο
  • Εισόδημα από €10,001 έως €20,000: 10% φόρος
  • Εισόδημα από €20,001 έως €30,000: 15% φόρος
  • Εισόδημα άνω των €30,000: 20% φόρος

Το πρόγραμμα θα ζητά από τον χρήστη να εισάγει το ετήσιο εισόδημά του και στη συνέχεια θα εμφανίζει το ποσό του φόρου.

Απαιτούμενες Παράμετροι:

  • annualIncome: ένα double που αντιπροσωπεύει το ετήσιο εισόδημα του χρήστη.

Κωδικός Παραγωγής Εξόδου: Το πρόγραμμα θα εμφανίζει το ποσό του φόρου σε ευρώ, π.χ., “Your income tax is: €XXXX”.

Ερώτημα 11

Γράψτε ένα πρόγραμμα που κατατάσσει τη θερμοκρασία σε διαφορετικές καιρικές συνθήκες με βάση την τιμή σε Κελσίου που δίνεται:

  • Κάτω από 0°C: “Freezing”
  • Από 0°C έως 10°C: “Cold”
  • Από 11°C έως 20°C: “Cool”
  • Από 21°C έως 30°C: “Warm”
  • Πάνω από 30°C: “Hot”

Το πρόγραμμα θα ζητά από τον χρήστη να εισάγει τη θερμοκρασία σε Κελσίου και στη συνέχεια θα εμφανίζει την αντίστοιχη καιρική συνθήκη.

Απαιτούμενες Παράμετροι:

  • temperature: ένας ακέραιος που αντιπροσωπεύει τη θερμοκρασία σε Κελσίου.

Κωδικός Παραγωγής Εξόδου: Το πρόγραμμα θα εμφανίζει την καιρική συνθήκη στα Αγγλικά, π.χ., “Freezing”, “Cold”, “Cool”, “Warm”, ή “Hot”.

Ερώτημα 12

Ζητήστε από τον χρήστη την τελική τιμή ενός προϊόντος και το ποσοστό ΦΠΑ που περιλαμβάνεται σε αυτήν, και υπολογίστε την αποφορολογημένη τιμή.

Οδηγίες:

  1. Ζητήστε από τον χρήστη την τελική τιμή του προϊόντος (συμπεριλαμβανομένου του ΦΠΑ) και το ποσοστό του ΦΠΑ.
  2. Υπολογίστε την αποφορολογημένη τιμή χρησιμοποιώντας με τον τύπο: NetPrice = FinalPrice / (1 + VATPercentage/100)
  3. Εκτυπώστε το αποτέλεσμα.

Ερώτημα 13

Δημιουργήστε ένα πρόγραμμα που αξιολογεί την επιλεξιμότητα δανείου με βάση τη βαθμολογία πίστωσης. Τα κριτήρια επιλεξιμότητας είναι τα εξής:

  • Βαθμολογία κάτω από 500: “High Risk - Loan Denied”
  • Βαθμολογία από 500 έως 650: “Medium Risk - Higher Interest Rate”
  • Βαθμολογία από 651 έως 750: “Low Risk - Standard Interest Rate”
  • Βαθμολογία πάνω από 750: “Very Low Risk - Preferred Interest Rate”

Το πρόγραμμα θα ζητά από τον χρήστη να εισάγει τη βαθμολογία πίστωσης και στη συνέχεια θα εμφανίζει το αντίστοιχο μήνυμα επιλεξιμότητας δανείου.

Απαιτούμενες Παράμετροι:

  • creditScore: ένας ακέραιος που αντιπροσωπεύει τη βαθμολογία πίστωσης του χρήστη.

Κωδικός Παραγωγής Εξόδου: Το πρόγραμμα θα εμφανίζει το μήνυμα επιλεξιμότητας δανείου στα Αγγλικά, π.χ., “High Risk - Loan Denied”, “Medium Risk - Higher Interest Rate”, κ.λπ.