دورة جافا: الطريق لإحتراف البرمجة من الصفر

 

عرفنا كيفية طباعة جملة أو سطر في لغة الجافا بواسطة ( System.out.print )، لكن ولكي يصبح البرنامج أكثر إفادة فلا يجب فقط طباعة الكلمات بل يجب أيضاً قراءة سطر الإدخال ( ما يقوم المستخدم بكتابته ) ولذلك وكأي لغة برمجة أخرى، فإن جافا تتوفر أيضاً على مكتبات لقراءة سطر الإدخال.

قراءة سطر الإدخال في لغة البرمجة جافا هي مختلفة عن لغة السي مثلاً، ففي هذه الأخيرة تتم القراءة بمساعدة scanf، لكن في لغة جافا فهناك عدة طرق لقراءة سطر الإدخال. في هذا الدرس سنتطرق لطريقة جديدة تم دمجها مؤخراً في لغة الجافا (JDK 5.0) لتصبح بذلك أقوى الطرق لقراءة سطر الإدخال.

الطريقة تتم بمساعدة كلاس ( class ) تأتي معرفة و مدمجة مع JDK ( أدوات تطوير جافا )، هذه الكلاس هي الكلاس ( Java.util.Scanner )، وهي قوية جداً حيث أنه يمكنها ليس فقط قراءة أسطر الإدخال التي يقوم المستخدم بكتابتها، بل يمكنها أيضاً قراءة محتوى الملفات.

الكلاس Scanner وكما يدل على ذلك اسمها، فيمكن أن نترجمها بالعربي إلى الماسح، وكلنا نعرف أداة الماسح الضوئي التي تقوم بمسح وثيقة معينة وتحويلها لوثيقة رقمية. هذه الكلاس تقوم بنفس العمل ! فهي تقوم بمسح كل ما تمت كتابته من طرف المستخدم ليتم تخزينه في متغير للإشتغال به في البرنامج .

 

6. قراءة سطر الإدخال في الجافا

in-and-out

 

كيفية إستعمال الكلاس Scanner

قراءة الأعداد

الأعداد الطبيعية

الأعداد العشرية

قراءة الكلمات والأسطر

قراءة الكلمات

قراءة حرف واحد

إستعمال الكلاس سكانر في حلقة

إضافة : قراءة محتوى الملفات

 

1.6 كيفية إستعمال الكلاس Scanner

الكلاس هي سهلة الاستخدام وذلك لأن جميع وظائفها معرفة من طرف الجافا مسبقاً يكفي فقط تتبع الخطوات البسيطة المشروحة هنا.

أولاً يجب إستدعاء الكلاس Scanner ( وهي الكلاس التي تحتوي على وظائف القراءة من سطر الإدخال )من مكتبة الجافا بالأمر التالي :


// هنا يتم إستدعاء الكلاس سكانر
import java.util.Scanner;  


بعد ذلك يجب تعريف كائن ( object ) له نفس خصائص الكلاس، هذا الكائن يمكن تسميته بأي إسم، لكن من الأحسن أن يكون الإسم ذو دلالة تدل على وظيفته، الهدف منه هو معرفة كيفية تسجيل معلومات يدخلها المستخدم من لوحة المفاتيح فقط. وكنت قد تطرقت لمفهوم الكائن في درس تاريخ وانواع البرمجة في فقرة : البرمجة غرضية التوجه، المرجو مراجعة الفقرة. يكفي معرفة طريقة كيفية إستعمال الكلاس سكانر أما المفاهيم بالتدقيق فسيأتي شرحها في مراحل مقبلة بالتفصيل إن شاء الله.

هنا اخترت إسم الكائن : input ( ومعناها الإدخال وسيتم تخزين فيه ما قام المستخدم بكتابته عن طريق لوحة المفاتيح ). هذا الكائن يتم تعريفه في الكلاس الأساسية ( main class ) هكذا :



// نقوم بتعريف كائن إسمه إنبوت له نفس خصائص الكلاس سكانر
Scanner input = new Scanner(System.in);


ثم نقوم بقراءة ما أدخله المستخدم على حسب ما نود تخزينه، فمثلاً إن كنا نريد قراءة عدد طبيعي، فسنستعمل على سبيل المثال الأمر التالي :



// إنبوت هو الكائن الذي تم تعريفه من الكلاس سكانر ليأخد خصائصها 

input.nextInt();



ويفضل دائماً أن نقوم بإنهاء هذا النوع من الكلاس عندما ننتهي من استعمالها بالسطر التالي  :




input.close();



 

يجب مراعاة كتابة Scanner بحرف S كبير وكذلك كتابة nextInt ب I كبيرة مع عدم نسيان الفاصلة المنقوطة

في سطر تعريف الكائن وكذلك في سطر القراءة بواسطة nextInt

هذا كل ما سنحتاجه للعمل بهذه الكلاس، وفي ما يلي أمثلة توضيحية أكثر.

 

2.6 قراءة الأعداد

كما نعلم هناك عدة أنواع من الأعداد ( أعداد طبيعية، عشرية ... ) ولكل نوع هناك نوع بيانات معين ( كما رأينا في الدرس السابق : أنواع البيانات والمتغيرات ). هذه الأعداد، كما يتم تخزينها في نوع معين من أنواع البيانات، يتم أيضاً قراءتها بنوع معين من أنواع البيانات.

 

1.2.6 الأعداد الطبيعية

الأعداد الطبيعية يتم قراءتها بواسطة السطور التالية :

  1. nextInt
  2. nextByte
  3. nextShort
  4. nextLong

مثال ل-nextInt ( ويمكن تطبيق نفس المثال على الأنواع الاخرى  ). هذا المثال يقرأ عمر المستخدم ويقوم بعرضه على الشاشة :





// هنا يتم إستدعاء الكلس سكانر
import java.util.Scanner;  
public class Input_int {
	 /**
	 * @author Ayoub El Hobbi
	 */
	public static void main(String[] args) {
		//  نقوم بتعريف متغير إسمه ايج
		int age;
        // نقوم بتعريف كائن إسمه إنبوت له نفس خصائص الكلاس سكانر
		Scanner input = new Scanner(System.in);
		// نطلب من المستخدم إدخال عمره
		System.out.println("how old are you ? : ");
		//  نقوم بتخزين عمر المستخدم في متغير ايج
		age = input.nextInt();
		System.out.println("your are " +age+ " years old");
		input.close();
	}
}




كما قمنا بشرح الطريقة؛ نقوم أولاً بتعريف كائن إسمه input، هذا الكائن سيأخد خصائص الكلاس سكانر، كخطوة تانية نطلب من المستخدم إدخال عمره، إبتداءً من هذه النقطة سوف ينتظر المترجم من المستخدم كي يقوم بإدخال عمره، عندها سيتم تخزين هذا العمر في المتغير age، وأخيراً تتم طباعته بالوظيفة : System.out.println.

 

2.2.6 الأعداد العشرية

الأعداد العشرية يمكن قراءتها بالسطور التالية :

  1. nextFloat
  2. nextDouble

مثال ل-nextDouble. هذا المثال يطلب من المستخدم حساب جمع عددين ويقوم بعرضه على الشاشة :






// هنا يتم إستدعاء الكلس سكانر 
import java.util.Scanner;  
public class Input_double {
	 /**
	 * @author Ayoub El Hobbi
	 */
	public static void main(String[] args) {
		
		// نقوم بتعريف كائن إسمه إنبوت له نفس خصائص الكلاس سكانر
		Scanner input = new Scanner(System.in);
		// نطلب من المستخدم إدخال جمع العددين 
		System.out.println("a = 1,5" );
		System.out.println("b = 1,3 ");
		System.out.println("a + b is : ");
		// نقوم بتخزين الجمع في متغير سي 
		double c = input.nextDouble();

		// نعرض الجمع على الشاشة 
		System.out.println("a + b = " +c);
		input.close();
	}
}






 

3.6 قراءة الكلمات والأسطر

قراءة الكلمات في الجافا تتم بنفس طريقة قراءة الأعداد.

 

1.3.6 قراءة الكلمات : nextLine

في لغة الجافا يمكنك وبمساعدة الكلاس Scanner قراءة سلسلة من الأحرف ( String )، كل ذلك يتم بنفس طريقة قراءة الأعداد، كما يمكنك أيضاً قراءة حرف واحد من سلسلة من الحروف، كل ذلك يتم بنفس الطريقة التي يتم بها قراءة الأعداد.

نبذة بسيطة عن Strings

رأينا في درس أنواع البيانات والمتغيرات، أنواع البيانات الجوهرية منها؛ int، double، float ... ولكن لم نتطرق لبعض الأنواع الاخرى ك arrays و-objects ولم نتطرق أيضاً لنوع البيانات الخاصة بسلسلة من الأحرف String، وذلك راجع لعدم توفر الخبرة الكافية لدى المستخدم لفهم هذه الأنواع، لكن لا بأس بتعريف بسيط ل-Strings مادمنا اننا سنتناولها في هذا الدرس.

Strings هي سلسلة من الأحرف ككلمة Mjma3، Ayoub، Mohamed .. لكن نوع البيانات String هو بخلاف أنواع البيانات الجوهرية، فهو عبارة عن كائن Object ( كما رأيتم في الأمثلة السابقة فقد استعملنا الكائن s من الكلاس سكانر - سنتطرق لكل هذا تفصيلاً لاحقاً بإذن الله ) وهو أيضاً بخلاف الكائنات العادية لا يتم تعريفه ب-new .. النوع String يتم تعريفه كما يتم تعريف الأنواع الجوهرية وينطبق عليه ما ينطبق على الكائنات.

نستعمل الوظيفة التالية : nextLine لقراءة النصوص في لغة البرمجة جافا بالطريقة التالية :





import java.util.Scanner;
public class Input_string {
	/**
	 * @author Ayoub El Hobbi
	 */
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.println("what is your name ? : " );
		
		// هنا يتم قراءة إسم المستخدم 
		String name = input.nextLine();
		System.out.println("hello " + name);
		input.close();
	}
}




ما نقوم به هنا هو تعريف String إسمه name ( في السطر 15 ) ونقرأ ما قام المستخدم بادخاله من كلمات، جمل، أرقام.. بالأمر nextLine .

 

4.2.6 قراءة حرف واحد : charAt

عيب هذه الكلاس ( Scanner ) أنها لا تحتوي على وظيفة لقراءة حرف واحد! لذلك ولقراءة حرف واحد يجب قراءة السطر بأكمله ثم بعد ذلك قراءة الحرف الأول من الكلمة أو الجملة التي قام المستخدم بادخالها. وذلك يتم كما في المثال التالي :




// هنا يتم إستدعاء الكلس سكانر 
import java.util.Scanner;  
public class Input_char {
	 /**
	 * @author Ayoub El Hobbi
	 */
	public static void main(String[] args) {
		
		// نقوم بتعريف كائن إسمه إنبوت له نفس خصائص الكلاس سكانر
		Scanner input = new Scanner(System.in);
		// نطلب من المستخدم إدخال الحرف الأول من إسمه 
		System.out.print("what is the first character of your name ? : ");
		// نقوم بتخزين ما قام بكتابته في متغير نايم 
		String name = input.nextLine();
		
		// نأخد الحرف الأول مما أدخله المستخدم .. فحتى وإن أدخل إسمه بأكمله،
		char firstChar = name.charAt(0);

		// وهنا تتم طباعته 
		System.out.println("the letter is :  " +firstChar);
		input.close();
	}
}




كما رأينا في هذا المثال فحتى وإن قام المستخدم بكتابة إسمه بأكمله يمكننا تخزنن فقط الحرف الأول من الكلمة، وكما يمكن تخزين موضع الحرف الأول من الكلمة، يمكن أيضاً تخزين الموضيع التاني، الثالث ... وذلك بتعويض رقم 0 في charAt بمثلاً رقم 1.

لنأخد مثلاً إسم Ayoub. أول حرف من هذا الإسم هو a وهو يحمل الرقم 0 في charAt، ثاني حرف يحمل الرقم 1، وهكذا ... يمكنك تجربة ذلك بنفسك :)

 

ملاحظة :

لا تحاول أبداً قراءة نص بمساعدة nextLine بعد قراءة عدد بمساعدة nextInt ! لأنه ببساطة لن يشتغل معك !

 

مثال





import java.util.Scanner;
public class scanner {
	/**
	 * @author Ayoub El Hobbi
	 */
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		
		System.out.println("how old are you ? : ");
		int age = input.nextInt();
		System.out.println("what is your name ? : " );
		String name = input.nextLine();
		System.out.println(name + "  " + age);
		input.close();
	}
}




يمكنك تجربة البرنامج ! سيقوم بالتوقف عند الإدخال الثاني ..

لكن ما هو الحل إن كنت تريد وبالضرورة قراءة عدد قبل النص ؟

الحل هو تعريف كائنين ( input1، input2) من ثم إستعمال كل واحد لقراءة نوع معين ( نص، عدد ) .. كالتالي :





import java.util.Scanner;
public class scanner {
	

     /**
	 * @author Ayoub El Hobbi
	 */
public static void main(String[] args) {
		Scanner input1 = new Scanner(System.in);
		Scanner input2 = new Scanner(System.in);
		
		System.out.println("how old are you ? : ");
		int age = input1.nextInt();
		System.out.println("what is your name ? : " );
		String name = input2.nextLine();
		System.out.println(name + " is " + age +" years old ! ");
		input1.close();
		input2.close();
	}
}




 

4.6 إستعمال الكلاس سكانر في حلقة ( loop )

رغم انني لم أتكلم عن الحلقات بعد ( loops ) ( سيتم التكلم عنها في درس مستقل بإذن الله قريباً ) لكن وددت أن اعطيكم مثال أيضاً عن إستعمال الكلاس سكانر في حلقة.

نبذة عن الحلقات

الحلقات كما يدل عليها اسمها، فهي تقوم بتنفيذ أمر أو أوامر لمرات عديدة حسب شرط معين، وكمثال على ذلك برنامج يقوم بطباعة جملة : hello kid دائماً ما دام عمر المستخدم أقل من 18 سنة، أما إن كان عمر المستخدم أكثر من 18 سنة فسيتوقف البرنامج.

مثال ثاني يمكن أن تستعمل فيه الحلقات : في جدول الضرب ! .. إن أردت مثلاً طباعة جدول الضرب لعدد 4 فيلزمك طباعة كل عدد مضروب في 4 ! بمساعدة الوظيفة (System.out.print )، لكن بمساعدة الحلقات يمكنك كتابة برنامج يقوم بإعادة أمر ضرب الأعداد بشكل تلقائي .

البرنامج الذي سنقوم ببرمجته سيقوم بجمع جميع الأعداد التي قام المستخدم بإدخالها مع بعدها، كما أن الحلقة تنتهي عند إدخال المستخدم لحرف مثلاً. البرنامج كالتالي :






import java.util.*;
public class SumLoop {
	
	/**
	 * @author Ayoub El Hobbi
	 */
    public static void main(String[] args) {
                     
        double sum = 0;         
        Scanner input = new Scanner(System.in);
        
        System.out.println("give some numbers : ( write 'sum' when you finished! ) ");
        
        // هنا بداية الحلقة التي تقوم بتخزين الأعداد المدخلة من طرف المستخدم
        while (input.hasNextDouble()) {
        	double n = input.nextDouble();
            sum = sum + n;
        }
        input.close(); 
        System.out.println("Sum of all Numbers is :  " + sum);
    }
}





5.6 إضافة : قراءة محتوى الملفات

الكلاس سكانر هي كلاس قوية، بحيث أنها تمكنك ليس فقط من قراءة ما قام المستخدم بادخاله بل أيضاً قراءة محتوى الملفات !

في المثال التالي سنقوم بقراءة محتوى ملف نصي ( ReadFromFile.txt ) وقد قمت برفعه لكم على الرابط التالي : ReadFromFile.txt ( بزر الفأرة الأيمن وإحفظه في المسار التالي : لنقل أن مكان تواجد مشاريعك هو - C:/Users/Ayoub/workspace ولنقل أن إسم مشروعك هو example إذاً فيجب عليك حفظ الملف في المسار التالي :  C:/Users/Ayoub/workspace/example/ReadFromFile.txt )

الكود يكون بالشكل التالي :

// نقوم بإستدعاء المكتبات الضرورية لإستعمال الكلاس







import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner; 
public class ReadFromFile 
{ 
	/**
	 * @author Ayoub El Hobbi
	 */
	public static void main( String[] args ) throws FileNotFoundException 
	{
		//  نقوم بتعريف كائن إسمه إنبوت له نفس خصائص الكلاس سكانر 
		Scanner input = new Scanner( new File("ReadFromFile.txt") );
		// هنا نستعمل حلقة لقراءة كل سطر على حدة	
		while ( input.hasNextLine() )
			// هنا نقوم بطبع محتوى الملف بكل أسطره
			System.out.println( input.nextLine() );
		input.close();
	} 
}







الجديد في هذا الكود هو اضافة المكتبتين Java.io.File و java.io.FileNotFoundException . المكتبة الأولى تمكننا من قراءة الملف من على مجلد المشروع، أما التانية فهي لمعالجة خطأ عدم تواجد الملف المطلوب.

كخطوة أولى نقوم بالإشارة للملف الذي نريد قراءة محتواه من السطر 13، بعد ذلك نقوم بعمل حلقة تقرأ كل سطر على حدة من السطر 16، وأخيراً نقوم بطبع جميع الأسطر .

 

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

 

تحميل جميع الأكواد المستعملة في هذا الدرس : Input.rar

هذا الملف يحتوي كذلك على ملف ReadFromFile.txt. لفتح الأكواد في اكليبس، انشئ مشروع جافا جديد، وقم بسحب الملفات لمجلد src، أما الملف ففي فقرة قراءة محتوى ملف مشروح كيفية التعامل معه.