الكلية الجامعية للعلوم التطبيقيةبرمجة 1
English
المحاضرة 5 · 100 دقيقة

الإدخال من لوحة المفاتيح باستخدام Scanner

اليوم يتوقف برنامجك لأول مرة، وينتظر ما ستكتبه أنت.

في نهاية هذه المحاضرة ستكون قادرًا على

  1. تشرح دور المدخلات والمعالجة والمخرجات في أي برنامج
  2. تجهّز Scanner بالاستيراد والإنشاء، وتقرأ به من لوحة المفاتيح
  3. تختار دالة القراءة المناسبة لكل نوع بيانات، وتقرأ حرفًا واحدًا عند الحاجة
  4. تكتب رسالة طلب واضحة قبل كل قراءة
  5. تشخّص فخ nextInt متبوعًا بـ nextLine وتصلحه
  6. تفسّر الاستثناء InputMismatchException وتكتب برامج حسابية تتفاعل مع المستخدم
محتويات المحاضرة
  1. حتى اليوم، كل برامجك تعطي الجواب نفسه في كل تشغيل
  2. الآن يتوقف برنامجك وينتظرك
  3. ثلاثة أسطر تصل برنامجك بلوحة المفاتيح
  4. لكل نوع بيانات دالة قراءة خاصة به
  5. رسالة الطلب تخبر المستخدم بما يجب أن يكتبه
  6. next تقرأ كلمة، وnextLine تقرأ ما تبقى من السطر
  7. لا توجد nextChar، فنأخذ أول حرف من الكلمة
  8. nextInt تترك ضغطة Enter خلفها، فتلتقطها nextLine
  9. الإصلاح: استهلك ضغطة Enter بـ nextLine إضافية
  10. إذا كتب المستخدم نصًا بدل العدد، يتوقف البرنامج باستثناء
  11. الآلة الحاسبة: مدخلان وأربع عمليات
  12. مساحة المستطيل: ابدأ بالسؤال: ما المدخلات؟
  13. تحويل الحرارة: المعادلة نفسها لأي قيمة يكتبها المستخدم
  14. التمرين النهائي: بطاقة طالب من لوحة المفاتيح
  15. أسئلة المراجعة
الجزء الأول: البرنامج يستمع إليك

حتى اليوم، كل برامجك تعطي الجواب نفسه في كل تشغيل

كل قيمة استخدمناها حتى الآن كتبناها بأنفسنا داخل الكود. شغّل البرنامج التالي عشر مرات، وسيحيّي سارة عشر مرات. ولكي يحيّي شخصًا آخر، يجب أن تفتح الكود وتعدّله.

برنامج لا يعرف إلا سارة

شغّله مرتين. هل يمكن لشخص لا يعرف Java أن يجعله يحيّيه باسمه؟

public class FixedGreeting {
    public static void main(String[] args) {
        String name = "Sara";
        System.out.println("Hello, " + name + "!");
    }
}
الناتج
Hello, Sara!
المدخلات

ما يأتي من خارج البرنامج: مبلغ تكتبه في الصراف الآلي، أو درجات الطالب.

المعالجة

ما يفعله البرنامج بالقيم: يقارن الرصيد، أو يحسب المعدل.

المخرجات

ما يعرضه البرنامج: النقود والإيصال، أو المعدل النهائي.

الآن يتوقف برنامجك وينتظرك

هذه لحظة مميزة في رحلتك: البرنامج التالي لا يعرف جوابه حين تضغط «تشغيل»، لأن جزءًا منه ما زال عندك أنت.

برنامجك الأول الذي يستمع

اضغط «تشغيل». سيتوقف البرنامج ويظهر مربع إدخال. اكتب اسمك واضغط Enter. ثم شغّله مجددًا واكتب اسم زميلك: الكود نفسه، والجواب مختلف.

import java.util.Scanner;

public class Greeting {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("What is your name? ");
        String name = input.nextLine();
        System.out.println("Hello, " + name + "!");
    }
}

ثلاثة أسطر تصل برنامجك بلوحة المفاتيح

الاستيراد

Scanner صنف جاهز في الحزمة java.util. اكتب هذا السطر في أعلى الملف، قبل class وبعد package إن وُجد.

import java.util.Scanner;
الإنشاء

اصنع قارئًا واحدًا وأعطه اسمًا. يعني System.in لوحة المفاتيح. واسم input من اختيارنا.

Scanner input = new Scanner(System.in);
القراءة

اطلب من القارئ القيمة التالية وضعها في متغير من النوع المناسب.

int age = input.nextInt();

المترجم لا يعرف Scanner

نسينا سطرًا واحدًا. أضفه حتى يعمل البرنامج.

public class Ready {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Scanner is ready");
    }
}
رسالة المترجمcannot find symbol
أظهر التصحيح
import java.util.Scanner;

public class Ready {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Scanner is ready");
    }
}
الناتج
Scanner is ready

لماذا؟ Scanner ليس جزءًا من الأساسيات التي يعرفها المترجم تلقائيًا. الرسالة تقول إنه لا يجد الرمز، ولا تذكر الاستيراد أبدًا، فتذكّر هذا السبب كلما رأيتها مع Scanner.

من أين يقرأ؟

أنشأنا القارئ دون أن نخبره من أين يقرأ.

import java.util.Scanner;

public class Ready {
    public static void main(String[] args) {
        Scanner input = new Scanner();
        System.out.println("Scanner is ready");
    }
}
رسالة المترجمno suitable constructor found for Scanner(no arguments)
أظهر التصحيح
import java.util.Scanner;

public class Ready {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Scanner is ready");
    }
}
الناتج
Scanner is ready

لماذا؟ يحتاج Scanner إلى مصدر يقرأ منه، ولا يختار لوحة المفاتيح من تلقاء نفسه. الرسالة طويلة ومخيفة، لكن عبارة «no arguments» تكفي: لم تعطه شيئًا بين القوسين.

لكل نوع بيانات دالة قراءة خاصة به

الدالةتقرأالنوعيكتب المستخدم
nextInt()عددًا صحيحًاint19
nextDouble()عددًا عشريًاdouble3.75
next()كلمة واحدة، حتى أول مسافةStringSara
nextLine()السطر كله، بما فيه المسافاتStringSara Ali
nextBoolean()true أو falsebooleantrue

أربع قراءات في برنامج واحد

شغّل البرنامج وأجب عن كل سؤال. لاحظ أن البرنامج يتوقف عند كل قراءة بالترتيب.

import java.util.Scanner;

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

        System.out.print("Age: ");
        int age = input.nextInt();
        System.out.print("GPA: ");
        double gpa = input.nextDouble();
        System.out.print("City: ");
        String city = input.next();
        System.out.print("Passed (true or false): ");
        boolean passed = input.nextBoolean();

        System.out.println("Age: " + age);
        System.out.println("GPA: " + gpa);
        System.out.println("City: " + city);
        System.out.println("Passed: " + passed);
    }
}

أي دالة تناسب قراءة سعر كتاب مثل 12.5؟

تريد قراءة عنوان كامل مثل 12 Omar Street. أي دالة تناسبه؟

رسالة الطلب تخبر المستخدم بما يجب أن يكتبه

Scanner لا يطبع شيئًا. إذا لم تطبع رسالة قبل القراءة، فسيجد المستخدم برنامجًا صامتًا لا يعرف ماذا يريد منه.

برنامج صامت

شغّله كأنك لم ترَ الكود من قبل: ماذا تكتب؟ ثم أضف قبل كل قراءة رسالة باستخدام print، مثل "Length in metres: ".

import java.util.Scanner;

public class Silent {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double length = input.nextDouble();
        double price = input.nextDouble();
        System.out.println(length * price);
    }
}

نفضّل print في الرسائل لأنها تترك المؤشر على السطر نفسه، فيكتب المستخدم بجوار السؤال. أما println فتنقله إلى سطر جديد.

الأسلوبان معًا

هذا المختبر يعطي البرنامج القيمتين 19 و3.5 تلقائيًا. قارن شكل الرسالتين في الناتج.

import java.util.Scanner;

public class Prompts {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Enter your age:");
        int age = input.nextInt();
        System.out.print("Enter your GPA: ");
        double gpa = input.nextDouble();
        System.out.println("Age " + age + ", GPA " + gpa);
    }
}
الناتج
Enter your age:
Enter your GPA: Age 19, GPA 3.5

next تقرأ كلمة، وnextLine تقرأ ما تبقى من السطر

تخيّل ما تكتبه شريطًا من الحروف يمر أمام Scanner، وكل قراءة تأخذ جزءًا من هذا الشريط وتتقدم. ما لم يُقرأ يبقى في مكانه للقراءة التالية.

كتب المستخدم Sara Ali Omar ثم Enter. ماذا يطبع البرنامج؟

import java.util.Scanner;

public class Words {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String first = input.next();
        String rest = input.nextLine();
        System.out.println("[" + first + "]");
        System.out.println("[" + rest + "]");
    }
}
أظهر الناتج
الناتج
[Sara]
[ Ali Omar]

لماذا؟ تأخذ next الكلمة الأولى وتتوقف قبل المسافة، فتبدأ nextLine من تلك المسافة وتأخذ ما تبقى. الأقواس المربعة تكشف المسافة التي كانت ستختفي عن عينيك.

جرّب بنفسك

شغّله واكتب اسمًا من كلمتين. ثم بدّل next إلى nextLine وشغّله مجددًا بالاسم نفسه.

import java.util.Scanner;

public class WordOrLine {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Full name: ");
        String name = input.next();
        System.out.println("Welcome, " + name);
    }
}

لا توجد nextChar، فنأخذ أول حرف من الكلمة

char grade = input.next().charAt(0);
next() تعطي نصًا، وcharAt(0) تأخذ منه الحرف في الموقع 0، أي الأول.

اقرأ تقديرًا

شغّله واكتب B. ثم شغّله واكتب Excellent. ثم غيّر 0 إلى 1 وشغّله مرة أخرى بالكلمة Excellent.

import java.util.Scanner;

public class Grade {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Your grade: ");
        char grade = input.next().charAt(0);
        System.out.println("Grade stored: " + grade);
    }
}

كتب المستخدم Hello. ماذا يطبع البرنامج؟

import java.util.Scanner;

public class FirstLetter {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        char letter = input.next().charAt(0);
        System.out.println(letter);
    }
}
أظهر الناتج
الناتج
H

لماذا؟ القيمة 0 هي موقع الحرف وليست ما يُطبع. ويحمل char حرفًا واحدًا فقط، فيبقى H وتُهمل بقية الكلمة.

نص في صندوق حرف

هذا ما يحدث لو كتبت char grade = input.next();. أصلحه حتى يطبع البرنامج A.

public class CharBox {
    public static void main(String[] args) {
        String word = "A";
        char grade = word;
        System.out.println(grade);
    }
}
رسالة المترجمincompatible types: String cannot be converted to char
أظهر التصحيح
public class CharBox {
    public static void main(String[] args) {
        String word = "A";
        char grade = word.charAt(0);
        System.out.println(grade);
    }
}
الناتج
A

لماذا؟ حتى لو كان النص حرفًا واحدًا، فإنه يبقى String. لا يحوّله المترجم إلى char من تلقاء نفسه، بل عليك أن تأخذ الحرف منه بـ charAt(0).

الجزء الثاني: الفخاخ والأخطاء

nextInt تترك ضغطة Enter خلفها، فتلتقطها nextLine

هذا أشهر فخ في Scanner، وسيقع فيه كل واحد منكم مرة. الكود يبدو صحيحًا تمامًا ويُترجم دون خطأ. جرّبه أولًا: اكتب عمرك، واضغط Enter، وانتظر سؤال الاسم.

البرنامج الذي لا ينتظر

شغّله. هل أتيحت لك فرصة لكتابة اسمك؟

import java.util.Scanner;

public class Trap {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Age: ");
        int age = input.nextInt();
        System.out.print("Name: ");
        String name = input.nextLine();
        System.out.println("[" + name + "] is " + age);
    }
}

المدخلات هنا سطران جاهزان: 19 ثم Sara Ali. ماذا يطبع البرنامج؟

import java.util.Scanner;

public class Trap {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Age: ");
        int age = input.nextInt();
        System.out.print("Name: ");
        String name = input.nextLine();
        System.out.println("[" + name + "] is " + age);
    }
}
أظهر الناتج
الناتج
Age: Name: [] is 19

لماذا؟ أخذت nextInt الرقمين 19 فقط. وبقيت ضغطة Enter في الشريط، فوجدتها nextLine فورًا، وفهمت منها أن السطر انتهى وهو فارغ. أما Sara Ali فلم يقرأها أحد.

القراءةماذا تأخذ؟ماذا يبقى في الشريط؟
nextInt()19ضغطة Enter، ثم Sara Ali
nextLine()لا شيء سوى ضغطة EnterSara Ali، ولن يقرأها أحد

الإصلاح: استهلك ضغطة Enter بـ nextLine إضافية

نضيف سطرًا واحدًا بعد nextInt يأخذ ضغطة Enter ويرميها، دون أن نحفظها في أي متغير. بعدها يصبح الشريط نظيفًا، وتنتظر nextLine الاسم الحقيقي.

الإصلاح بالمدخلات نفسها

المدخلات جاهزة: 19 ثم Sara Ali. قارن الناتج مع الناتج السابق.

import java.util.Scanner;

public class TrapFixed {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Age: ");
        int age = input.nextInt();
        input.nextLine(); // Throw away the Enter left by nextInt
        System.out.print("Name: ");
        String name = input.nextLine();
        System.out.println("[" + name + "] is " + age);
    }
}
الناتج
Age: Name: [Sara Ali] is 19

والآن أنت تكتب

شغّله واكتب عمرك واسمك الكامل. هذه المرة ينتظرك البرنامج. اضغط «تتبّع سطرًا سطرًا» وراقب أين يتوقف في كل قراءة، ثم احذف السطر الإضافي وقارن.

import java.util.Scanner;

public class TrapFixedLive {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Age: ");
        int age = input.nextInt();
        input.nextLine();
        System.out.print("Name: ");
        String name = input.nextLine();
        System.out.println("Hello " + name + ", you are " + age);
    }
}
القراءة الأولىالقراءة التاليةهل يوجد فخ؟
nextInt()nextInt()لا: تتخطى ضغطة Enter
nextInt()next()لا: تتخطى ضغطة Enter
nextDouble()nextLine()نعم: الفخ نفسه
next()nextLine()نعم: الفخ نفسه
nextLine()nextInt()لا: nextLine تأخذ ضغطة Enter معها

أي ترتيب يحتاج إلى nextLine إضافية بين القراءتين؟

العمر ثم الاسم

اطبع الرسالة Age: واقرأ عددًا صحيحًا، ثم اطبع الرسالة Name: واقرأ سطرًا كاملًا، ثم اطبع Sara Ali is 19 بالقيم التي قرأتها.

import java.util.Scanner;

public class AgeThenName {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // Read the age, then the full name, then print the sentence

    }
}
stdin
19
Sara Ali
الناتج المتوقع
Age: Name: Sara Ali is 19
تلميح 1

إذا ظهر الاسم فارغًا فقد وقعت في الفخ.

تلميح 2

أضف input.nextLine(); مباشرة بعد nextInt.

الحل
import java.util.Scanner;

public class AgeThenName {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Age: ");
        int age = input.nextInt();
        input.nextLine();
        System.out.print("Name: ");
        String name = input.nextLine();
        System.out.println(name + " is " + age);
    }
}

إذا كتب المستخدم نصًا بدل العدد، يتوقف البرنامج باستثناء

المترجم يفحص الكود قبل التشغيل، لكنه لا يعرف ما سيكتبه المستخدم لاحقًا. لذلك يظهر هذا الخطأ أثناء التشغيل فقط، ويسمى استثناء. لنتعمّد إحداثه الآن.

حطّم البرنامج عمدًا

شغّله واكتب 19. ثم شغّله واكتب abc، واقرأ الشرح الذي يظهر تحت الناتج. ثم جرّب 19.5: ماذا تتوقع؟

import java.util.Scanner;

public class BreakIt {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("How old are you? ");
        int age = input.nextInt();
        System.out.println("Next year you will be " + (age + 1));
        System.out.println("Goodbye");
    }
}

كتب المستخدم abc. ماذا يظهر في المخرجات العادية، دون رسالة الخطأ؟

import java.util.Scanner;

public class Stops {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Start");
        int age = input.nextInt();
        System.out.println("Age: " + age);
        System.out.println("End");
    }
}
أظهر الناتج
الناتج
Start

لماذا؟ يوقف الاستثناء البرنامج عند السطر الذي حدث فيه، فلا تُنفَّذ الأسطر التي بعده. ولا تتحول abc إلى صفر: لم تُخزَّن أي قيمة في age.

الدالةيكتب المستخدمالنتيجة
nextInt()abcInputMismatchException
nextInt()19.5InputMismatchException
nextDouble()abcInputMismatchException
nextDouble()1919.0
nextBoolean()yesInputMismatchException
next()19النص "19"

كتب المستخدم 19 في nextDouble. ماذا يطبع البرنامج؟

import java.util.Scanner;

public class WholeInDouble {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double value = input.nextDouble();
        System.out.println(value);
    }
}
أظهر الناتج
الناتج
19.0

لماذا؟ كل عدد صحيح يصلح قيمة عشرية، فيقبله nextDouble. أما العكس فلا يصح: 19.5 ليست عددًا صحيحًا، ولذلك ترفضها nextInt.

الجزء الثالث: برامج كاملة

الآلة الحاسبة: مدخلان وأربع عمليات

  1. المدخلاتاقرأ عددين من نوع double مع رسالة طلب لكل منهما.
  2. المعالجةاحسب الجمع والطرح والضرب والقسمة.
  3. المخرجاتاطبع كل نتيجة على سطر، بنص يوضح معناها.

آلتك الحاسبة

جرّب 7 و2. ثم جرّب 5 و0: لاحظ النتيجة Infinity في القسمة. ثم أعط الآلة لزميلك واطلب منه أن يختبرها.

import java.util.Scanner;

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

        System.out.print("First number: ");
        double a = input.nextDouble();
        System.out.print("Second number: ");
        double b = input.nextDouble();

        System.out.println(a + " + " + b + " = " + (a + b));
        System.out.println(a + " - " + b + " = " + (a - b));
        System.out.println(a + " * " + b + " = " + (a * b));
        System.out.println(a + " / " + b + " = " + (a / b));
    }
}

المدخلات: 7 ثم 2. لاحظ الأقواس حول الجمع. ماذا يطبع البرنامج؟

import java.util.Scanner;

public class Sum {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double a = input.nextDouble();
        double b = input.nextDouble();
        System.out.println("Sum: " + a + b);
        System.out.println("Sum: " + (a + b));
    }
}
أظهر الناتج
الناتج
Sum: 7.02.0
Sum: 9.0

لماذا؟ هذا الفخ من محاضرة المتغيرات، وأصبح أخطر الآن لأن القيم من المستخدم. دون أقواس تُلصق الأعداد بالنص، وبالأقواس تُجمع أولًا.

مساحة المستطيل: ابدأ بالسؤال: ما المدخلات؟

السؤالالجواب
ما المدخلات؟العرض والارتفاع، وقد يكون فيهما كسر
ما المعالجة؟width * height, 2 * (width + height)
ما المخرجات؟المساحة والمحيط

مساحة المستطيل ومحيطه

اطبع الرسالة Width: واقرأ عددًا عشريًا، ثم الرسالة Height: واقرأ عددًا عشريًا. ثم اطبع Area: متبوعة بالمساحة على سطر، وPerimeter: متبوعة بالمحيط على سطر.

import java.util.Scanner;

public class Rectangle {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // Read the width and height, calculate, then print

    }
}
stdin
3
4
الناتج المتوقع
Width: Height: Area: 12.0
Perimeter: 14.0
تلميح 1

استخدم nextDouble للقيمتين، حتى إذا كُتب عدد صحيح.

تلميح 2

المحيط يحتاج إلى أقواس: 2 * (width + height).

الحل
import java.util.Scanner;

public class Rectangle {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Width: ");
        double width = input.nextDouble();
        System.out.print("Height: ");
        double height = input.nextDouble();
        double area = width * height;
        double perimeter = 2 * (width + height);
        System.out.println("Area: " + area);
        System.out.println("Perimeter: " + perimeter);
    }
}

تحويل الحرارة: المعادلة نفسها لأي قيمة يكتبها المستخدم

المعادلة: F = C * 9 / 5 + 32. نستخدم printf لعرض رقم عشري واحد بعد الفاصلة، كما تعلمنا في المحاضرة السابقة.

من مئوية إلى فهرنهايت

جرّب 37 و100 و-40. ما الغريب في القيمة الأخيرة؟

import java.util.Scanner;

public class Temperature {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Celsius: ");
        double celsius = input.nextDouble();
        double fahrenheit = celsius * 9 / 5 + 32;
        System.out.printf("%.1f C = %.1f F%n", celsius, fahrenheit);
    }
}

المدخل هو 25. ماذا يطبع البرنامج؟

import java.util.Scanner;

public class Weather {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Celsius: ");
        double celsius = input.nextDouble();
        System.out.printf("%.1f F%n", celsius * 9 / 5 + 32);
    }
}
أظهر الناتج
الناتج
Celsius: 77.0 F

لماذا؟ print تبقي رسالة الطلب على السطر نفسه، والمدخل الآلي لا يظهر في الناتج. أما الحساب فهو 25 × 9 = 225، ثم ÷ 5 = 45، ثم + 32 = 77.

من فهرنهايت إلى مئوية

اطبع الرسالة Fahrenheit: واقرأ عددًا عشريًا، ثم حوّله بالمعادلة C = (F - 32) * 5 / 9، واطبع النتيجة بالشكل 212.0 F = 100.0 C برقم عشري واحد لكل قيمة.

import java.util.Scanner;

public class ToCelsius {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // Read the temperature, convert it, then print with printf

    }
}
stdin
212
الناتج المتوقع
Fahrenheit: 212.0 F = 100.0 C
تلميح 1

لا تنس الأقواس حول F - 32.

تلميح 2

استخدم القالب "%.1f F = %.1f C%n".

الحل
import java.util.Scanner;

public class ToCelsius {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Fahrenheit: ");
        double fahrenheit = input.nextDouble();
        double celsius = (fahrenheit - 32) * 5 / 9;
        System.out.printf("%.1f F = %.1f C%n", fahrenheit, celsius);
    }
}

التمرين النهائي: بطاقة طالب من لوحة المفاتيح

في محاضرة المتغيرات كتبنا قيم هذه البطاقة داخل الكود. اليوم يكتبها المستخدم، فيعمل البرنامج نفسه لكل طالب في الجامعة.

بطاقة الطالب

اقرأ بالترتيب: Age: عددًا صحيحًا، ثم Name: سطرًا كاملًا، ثم GPA: عددًا عشريًا، ثم Grade: حرفًا واحدًا. ثم اطبع Sara Ali, age 19 على سطر، وGPA 3.75, grade A على السطر التالي، مع رقمين عشريين للمعدل.

import java.util.Scanner;

public class StudentCardInput {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // Read age, name, GPA and grade, then print the card

    }
}
stdin
19
Sara Ali
3.75
A
الناتج المتوقع
Age: Name: GPA: Grade: Sara Ali, age 19
GPA 3.75, grade A
تلميح 1

الاسم يأتي بعد nextInt: هل تتذكر الفخ؟

تلميح 2

اقرأ الحرف بـ input.next().charAt(0).

تلميح 3

استخدم printf مع %.2f للمعدل و%c للحرف.

الحل
import java.util.Scanner;

public class StudentCardInput {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Age: ");
        int age = input.nextInt();
        input.nextLine();
        System.out.print("Name: ");
        String name = input.nextLine();
        System.out.print("GPA: ");
        double gpa = input.nextDouble();
        System.out.print("Grade: ");
        char grade = input.next().charAt(0);
        System.out.println(name + ", age " + age);
        System.out.printf("GPA %.2f, grade %c%n", gpa, grade);
    }
}

أسئلة المراجعة

ماذا تعني الرسالة cannot find symbol عند السطر الذي يحوي Scanner؟

متى يظهر InputMismatchException؟

لماذا نستخدم print لا println عادةً في رسالة الطلب؟

المدخلات: 3.5 ثم Sara. ماذا يطبع البرنامج؟

import java.util.Scanner;

public class ReviewTrap {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double gpa = input.nextDouble();
        String name = input.nextLine();
        System.out.println("[" + name + "] " + gpa);
    }
}
أظهر الناتج
الناتج
[] 3.5

لماذا؟ الفخ لا يخص nextInt وحدها. فكل دالة تقرأ قيمة دون السطر كاملًا تترك ضغطة Enter خلفها، وnextDouble واحدة منها.