سبد (0)

استفاده از کلاس Scanner در جاوا

در فصل 1، آموختید که چطور می توان با استفاده از دستور System.out یک خروجی را در مانیتور ایجاد کنید. دستور System.out به دستگاه استاندارد خروجی که معمولا یک مانیتور است، اشاره می کند. در حین برنامه نویسی، ممکن است بارها نیاز پیدا کنید که از کابر یک سری ورودی را دریافت کنید. برای انجام این کار، می توانید از دستور System.in استفاده کنید. این دستور به دستگاه استاندارد ورودی که معمولا یک کیبورد است، اشاره می کند. 

 شما می توانید با استفاده از متدهای  ()print و ()println انواع داده ها را نمایش دهید. بعنوان مثال شما می توانید با استفاده از این دو متد، یک مقدار از نوع double یا int یا String را نمایش دهید. اما اشیاء System.in خیلی انعطاف پذیر نیستند و طوری طراحی شده اند که تنها می توانند داده ها از نوع byte را بخوانند. و چون که شما اغلب می خواهید داده هایی  از دیگر انواع را دریافت کنید، به مشکل برخواهید خورد. خوشبختانه برنامه نویسان زبان جاوا، یک کلاس به نام Scanner طراحی کرده اند که باعث می شود دستور System.in انعطاف پذیر شود. 

برای ایجاد یک شیء Scanner و اتصال آن به System.in می توانید از دستور زیر استفاده کنید:

مثال (استفاده از کلاس Scanner در جاوا)

Scanner inputDevice = new Scanner(System.in);

 بخشی از دستور بالا، که در سمت چپ تساوی قرار دارد، یعنی Scanner inputDevice، یک شیء از نوع Scanner تعریف می کند و نام آن را (به طور اختیاری) inputDevice می گذارد. درست مثل عبارت int x که یک عدد صحیح با نام دلخواه x را تعریف می کند. اما هنوز در داخل آن چیزی قرار نگرفته است.

بخش دیگر دستور بالا که در سمت راست تساوی قرار دارد، یعنی (new Scanner(System.in درواقع یک شیء Scanner ایجاد می کند که به خاصیت System.in متصل شده است. به عبارت دیگر، شیء Scanner ایجاد شده، به دستگاه ورودی پیش فرض متصل شده است. در جاوا، هنگام ایجاد یک شیء، استفاده از کلمه ی کلیدی new الزامی است. در حقیقت هنگامی که می خواهیم اشیائی ایجاد کنیم که از نوع داده های ساده، پیچیده تر هستند، از کلمه ی کلیدی new استفاده می کنیم. 

  نکته: در فصل 4، می آموزیم که بخش دوم تعریف Scanner درواقع یک متد خاص به نام constructor را فراخوانی می کند که بخشی از کلاس از قبل نوشته شده ی Scanner است. در فصل 4، شما همچنین با کلمه ی کلیدی new آشنا خواهید شد. 

نقش عملگر تساوی در عبارت تعریف Scanner این است که مقدار شیء جدید را به شیء inputDevice انتساب دهد. 

 یک شیء Scanner ورودی های خود را به واحدهایی به نام tokens (علامت رمز) تقسیم می کند و هنگامی که با یک فاصله ی سفید مواجه می شود، آنها را از یکدیگر جدا می کند. حالا علامت های رمز به دست آمده می توانند با استفاده از چند متد مختلف به مقادیری تبدیل شوند. جدول 2.8 برخی از پرکاربرد ترین متدهایی که انواع داده های مختلف را از دستگاه ورودی پیش فرض می خوانند، به طور خلاصه نشان می دهد. هر کدام از آنها یک مقدار را از کیبورد دریافت می کنند و آن را بصورت یک نوع داده ی مناسب برمی گردانند. هنگامی که کاربر فاصله های سفید مناسبی را در کیبورد وارد کند، متد مرتبط با آن اجرا می شود و داده ها را دریافت می کند. متد ()nextLine تا زمانی که کاربر کلید Enter را فشار ندهد، هیچ داده ای را دریافت نمی کند. دیگر متدها، هنگامی که کاربر کلید های Enter یا space یا tab را فشار دهد، داده ها را دریافت می کنند. 

 

نکته: علاوه بر متد های جدول بالا، کلاس Scanner حاوی متدهای دیگری به نام های ()nextByte و ()nextFloat و ()nextLong و ()nextShort است که شیوه ی کار کردن آنها از نامشان پیدا است. 

نکته: کلاس Scanner دارای متدی به نام ()nextChar نیست. بنابراین برای دریافت یک کاراکتر تکی از کیبورد، می توانید از متد ()nextLine استفاده کنید و پس از آن از متد ()charAt  استفاده نمایید. در فصل " رشته ها " متد ()charAt را مورد بررسی قرار خواهیم داد. 

 


در عکس 2.10 یک برنامه را مشاهده می کنید که دو متد از  کلاس Scanner را مورد استفاده قرار می دهد. این برنامه یک رشته و یک عدد صحیح را از کیبورد می خواند و آنها را نمایش می دهد. در این برنامه کلاس Scanner چهار بار مورد استفاده قرار گرفته است، که در این تصویر با رنگ آبی نشان داده شده اند:

  • اولین عبارت رنگی، دستور  import java.util.Scanner است. این عبارت پکیج لازم برای کلاس Scanner را اضافه می کند. 
  • دومین عبارت رنگی، یک شیء از نوع Scanner به نام inputDevice را تعریف می کند. 
  • سومین عبارت رنگی، از متد ()nextLine برای دریافت یک خط از متن وارد شده توسط کیبورد استفاده می کند و آن را در متغیری به نام name قرار می دهد. 
  • چهارمین عبارت رنگی، از متد ()nextInt  برای دریافت یک عدد صحیح از کیبورد، استفاده می کند و آن را در متغیر age قرار می دهد. 

در عکس 2.11 می توانید نحوه ی اجرای این برنامه را مشاهده کنید.

 

 نتیجه:

 دستور ()print که در برنامه ی نشان داده شده در عکس 2.10 ، قبل از هر دستور ورودی قرار گرفته است، را می توان نمونه ای از  یک درخواست ورودی یا prompt در نظر گرفت. یک prompt(درخواست ورودی)، درواقع یک پیغام است که برای کاربر نمایش داده می شود و از او درخواست می کند تا یک ورودی را وارد نماید. همان طور که در عکس 2.10 مشاهده می کنید، تمامی درخواست های ورودی یا prompt ها در کلاس GetUserInfo با دو علامت بزرگتری و یک فاصله ی سفید پایان می یابند. 

 


مشکل در استفاده از متد ()nextLine بعد از دیگر متد های ورودی کلاس Scanner

اگر شما قبل از متد()nextLine،  از متدهای دریافت عدد، در کلاس Scanner استفاده کنید ، و یا از متد ()next استفاده کنید، با مشکل مواجه خواهید شد. به برنامه ی نشان داده شده در عکس 2.12 دقت کنید. این برنامه با برنامه ی نشان داده شده در عکس 2.10 یکسان است. با این تفاوت که ابتدا سن(age) کاربر درخواست می شود و پس از آن، نام کاربر درخواست می شود. عکس 2.13 نتیجه را نشان می دهد:

 

 نتیجه:

 همان طور که در عکس 2.13 مشاهده می کنید، کاربر به درستی سن(age) خود را وارد کرده است. اما پس از وارد شدن این عدد، پیغام وارد کردن نام(name) نشان داده می شود اما برنامه به کاربر اجازه نمی دهد تا نام خود را وارد کند. و سپس برنامه مستقیما دستور خروجی را اجرا می کند. همان طور که در عکس 2.13 مشاهده می کنید، نام کاربر در خروجی نشان داده نشده است. 

 هنگامی که شما با استفاده از کیبورد، کاراکترها را وارد می کنید، آنها به طور موقت در یک مکان موقت از حافظه، به نام keyboard buffer ذخیره می شوند. همچنین گاهی اوقات به keyboard buffer عبارت type-ahead  buffer نیز اطلاق می گردد. تمامی کلیدهای کیبورد، مثل کلید Enter در داخل keyboard buffer ذخیره می شوند. 

حال، مشکل بالا به این دلیل ایجاد می شود که کارکرد متد ()nextLine با دیگر دستورات کلاس Scanner متفاوت است:

  • متد های ()next و ()nextInt و ()nextDouble درواقع token بعدی را تا فاصله ی سفید بعدی در buffer دریافت می کنند. این فاصله ی سفید می تواند کلیدهای tab یا space یا Enter باشد. 
  • متد ()nextLine تمامی داده ها را می خواند تا زمانی که به یک کاراکتر Enter برسد. 

بنابراین وقتی برنامه ی نشان داده شده در عکس 2.13 اجرا می شود، سن کاربر درخواست می شود و او عدد 22 را وارد می کند. و سپس کلید Enter را فشار می دهد. حالا متد ()nextInt عدد 22 را دریافت می کند و کلید Enter را نادیده می گیرد. پس کلید Enter در داخل buffer ورودی هنوز باقی مانده است. سپس پیغام وارد کردن نام، نمایش داده می شود، حالا متد ()nextLine قبل از اینکه کاربر بتواند نام خود را وارد کند، آن کلید Enter باقی مانده را دریافت می کند و به کار خود پایان می دهد. 

 راه حل این مشکل ساده است. کافیست پس از فراخوانی متدهای ()next و ()nextInt یا ()nextDouble یک بار متد ()nextLine را به طور اضافی مورد فراخوانی قرار دهید. این کار باعث می شود که کاراکتر Enter باقی مانده از بین برود. سپس بدون توجه به اینکه چه ورودی را دریافت می کنید، برنامه ی شما به درستی کار خواهد کرد. 


عکس 2.14 یک برنامه را نشان می دهد که نسبت به عکس 2.12 تنها یک تغییر در آن ایجاد شده است. این تغییر را به صورت رنگی شده، نشان داده ایم. این عبارت رنگی، کلید Enter باقی مانده در بافر ورودی را دریافت می کند. با اینکه می توانید این کلید Enter باقی مانده را در داخل یک متغیر قرار دهید، اما نیازی به این کار نیست. هنگامی که شما یک ورودی دارید اما آن را بلا استفاده قرار می دهید، برنامه نویسان می گویند که این ورودی تحلیل رفته است(consumed). 

عکس 2.14 نشان می دهد که اگر متد ()nextInt را فراخوانی کنیم، این دستور یک عدد صحیح را قبول می کند. سپس وقتی که برای اولین بار متد ()nextLine را فراخوانی می کنیم، این دستور کلید Enter وارد شده پس از عدد صحیح را می پذیرد و از بین می برد. سپس وقتی که برای دومین بار متد ()nextLine را فراخوانی می کنیم، این متد نام وارد شده را به همراه کلید Enter دریافت می کند( و کلید Enter را دور می اندازد). عکس 2.15 نشان می دهد که برنامه ی اصلاح شده ی ما به درستی کار می کند. 

شماره 1: این دستور یک عدد صحیح را دریافت می کند.

شماره 2: این دستور، کلید Enter باقی مانده را از بین می برد(تحلیل می برد).

شماره 3: این دستور نام کاربر را می گیرد و کلید Enter وارد شده پس از نام را دور می اندازد. 

 

 


 ص 84 دو پاراگراف آخر ادامه داده شود. 

تمامی محصولات و خدمات این وبسایت، حسب مورد دارای مجوزهای لازم از مراجع مربوطه می‌باشند و فعالیت‌های این سایت تابع قوانین و مقررات جمهوری اسلامی ایران است.
logo-samandehi مجوز نشر دیجیتال از وزرات فرهنگ و ارشاد اسلامی پرداخت آنلاین -  بانک ملت معرفی بیاموز در شبکه سه