نحوۀ تعریف نوع ورودی کلاس Scanner در زبان برنامه‌نویسی جاوا


در آموزش قبل دیدیم که به چه نحوی می‌توان یک آبجکت (شیئ) از روی کلاس Scanner ساخته و آن را در برنامۀ خود مورد استفاده قرار داد. حال در ادامه قصد داریم تا به مباحث تکمیلی این کلاس مانند معرفی متدهایی به منظور محدود کردن کاربر جهت وارد کردن برخی دیتا تایپ خاص در قالب یکسری مثال کاربردی بپردازیم.

در فرآیند توسعۀ نرم‌افزار برخی مواقع نیاز داریم تا یکسری نوع دادۀ خاص تعریف کرده و کاربر را محدود به وارد کردن آن دسته از داده‌ها نماییم به طوری که مثلاً کاربران در بخش تعریف‌شده برای دریافت دیتای مربوط به سنِ خود امکان وارد کردن نام خود را نداشته باشند که پیاده‌سازی چنین سناریویی در زبان برنامه‌نویسی جاوا با استفاده از برخی متدهای کلاس Scanner امکان‌پذیر می‌باشد که در ادامه قصد داریم تا به معرفی این متدها بپردازیم.

برای این منظور، پروژه‌ای تحت عنوان ScannerInput ایجاد کرده و کلاسی به نام ScannerClass داخل آن می‌سازیم به طوری که در ابتدا کدی مانند زیر خواهیم داشت:

public class ScannerClass {
    public static void main(String[] args) {
    
    }
}

اکنون همان‌طور که در آموزش گذشته بیان کردیم، جهت استفاده از متدهای مختلف کلاس Scanner می‌باید ابتدا یک آبجکت از روی آن بسازیم که برای این منظور کد فوق را به صورت زیر تکمیل می‌نماییم:

import java.util.Scanner;
public class ScannerClass {
    public static void main(String[] args) {
        Scanner keyboardInput = new Scanner(System.in);
    }
}

همان‌طور که می‌بینیم، با استفاده از کیورد new آبجکتی جدید از روی کلاس Scanner تحت عنوان keyboardInput ساخته و در ادامه دستور System.in را جهت دریافت ورودی از صفحه‌کلید به آبجکت مذکور پاس می‌دهیم تا بتوانیم بعداً دیتای دریافتی از سمت کاربر را در متدهای تعریف‌شده داخل کلاس اسکنر مورد استفاده قرار دهیم.

در همین راستا، در ادامۀ آموزش برخی متدهای از پیش تعریف‌شدهٔ متعلق به کلاس Scanner را معرفی کرده و با نحوۀ پیاده‌سازی هر یک در قالب مثال‌هایی کاربردی آشنا خواهیم شد.

متد ()nextLine

در آموزش معرفی کلاس Scanner در زبان برنامه‌نویسی جاوا با نحوۀ عملکرد این متد آشنا شدیم و گفتیم که متد مذکور تمامی انواع دادۀ ورودی از سمت کاربر را تا زمان فشردن دکمۀ اینتر ذخیره و نگهداری می‌کند؛ بدین طریق می‌توان متد مذکور را روی آبجکت ساخته‌شده از روی این کلاس فراخوانی کرده سپس پردازش‌های مورد نظر را روی نتیجۀ ریترن‌شده اِعمال نمود که به منظور استفاده از قابلیت‌های این متد، کد فوق را به صورت زیر تکمیل می‌کنیم:

import java.util.Scanner;
public class ScannerClass {
    public static void main(String[] args) {
        Scanner keyboardInput = new Scanner(System.in);
        System.out.print("Please enter your input: ");
        System.out.println(keyboardInput.nextLine());
        keyboardInput.close();
    }
}

در کد فوق، ابتدا آبجکتی تحت عنوان keyboardInput از روی کلاس Scanner ساخته و در ادامه با استفاده از دستور System.in امکان دریافت ورودی از کنسول را برای برنامۀ خود فراهم کرده‌ایم. در سطر بعد، استرینگ «:Please enter your input» را در معرض دید کاربر قرار داده‌ایم تا بداند که برنامه چه کاری را از وی انتظار دارد. در ادامه، متد ()nextLine را روی آبجکت keyboardInput فراخوانی کرده و دیتای ریترن‌شده در نتیجۀ این فراخوانی را به متد ()println می‌دهیم تا بدین ترتیب دیتای ورودی از کاربر عیناً در کنسول چاپ شود. در نهایت، با اجرای کد فوق خواهیم داشت:

Please enter your input: This is a sentence 123 % &* @ ...
This is a sentence 123 % &* @ ...

همان‌طور که مشاهده می‌کنیم، با استفاده از متد ()nextLine می‌توانیم ترکیبی از حروف، کلمات، اعداد و حتی علائم را به عنوان دیتای ورودی به برنامه بدهیم و از همین روی استفاده از متد مذکور در صورتی مناسب می‌باشد که مثلاً از کاربر بخواهیم تا رمز عبوری برای خود تعریف نماید و بدین طریق رمز عبور وی را به عنوان دیتای دریافتی در اپلیکیشن ذخیره می‌نماییم.

متد ()next

متد ()next نیز مشابه متد پیشین عمل کرده و هر نوع دیتای ورودی از صفحه‌کلید را دریافت می‌کند با این تفاوت که دریافت دیتای ورودی را تا زمانی ادامه می‌دهد که به یک اِسپیس در استرینگ مورد نظر برسد بدین معنی که سایر داده‌های ورودی از اولین علامت اِسپیس به بعد را نادیده می‌گیرد که برای آشنایی بیشتر با نحوۀ کار این متد، کد مربوط به مثال قبل را به صورت زیر تغییر می‌دهیم:

import java.util.Scanner;
public class ScannerClass {
    public static void main(String[] args) {
        Scanner keyboardInput = new Scanner(System.in);
        System.out.print("Please enter your input: ");
        System.out.println(keyboardInput.next());
        keyboardInput.close();
    }
}

حال مجدد برنامه را اجرا کرده و در ادامه تعدادی کاراکتر و عدد پشت سر هم نوشته و یک اسپیس مابین آن‌ها قرار می‌دهیم سپس تعدادی کاراکتر و عدد دیگر می‌نویسیم و در نهایت دکمۀ اینتر را می‌زنیم که در خروجی خواهیم داشت:

Please enter your input: ABC123 EFG456
ABC123

در واقع، پس از اجرای برنامۀ فوق، در کنسول استرینگ «ABC123» را وارد کرده سپس یک فاصله قرار داده‌ایم و در ادامه استرینگی به صورت «EFG456» تایپ کرده و در نهایت دکمۀ اینتر را می‌زنیم و همان‌طور که می‌بینیم، متد ()next تنها استرینگ‌های قبل از اولین علامت اِسپیس را از ورودی می‌خواند و در ادامه دیتای مربوطه به متد ()println پاس داده شده و در خروجی چاپ می‌گردد. اکنون اگر بخواهیم تا برنامۀ فوق قابلیت دریافت دیتای ورودی را پس از علامت اسپیس نیز داشته باشد، یک مرتبۀ دیگر متد ()next را به صورت زیر روی آبجکت ساخته‌شده فراخوانی می‌نماییم:

import java.util.Scanner;
public class ScannerClass {
    public static void main(String[] args) {
        Scanner keyboardInput = new Scanner(System.in);
        System.out.print("Please enter your input: ");
        System.out.println(keyboardInput.next());
        System.out.println(keyboardInput.next());
        keyboardInput.close();
    }
}

در واقع، اجرای کد فوق و فراخوانی متد ()next در سطر ششم روی آبجکت ساخته‌شده از روی کلاس Scanner منجر بدین می‌شود تا دیتای ورودیِ مربوط به پیش از اولین اسپیس توسط متد ()println در کنسول چاپ شده و در ادامه با فراخوانی مجدد این متد ()next در سطر هفتم سایر داده‌های ورودیِ کاربر مابین اولین اِسپیس تا قبل از اِسپیس بعدی ذخیره شده و توسط متد ()println در کنسول نمایش داده می‌شوند که به عنوان یک مثال از اجرای برنامۀ فوق خواهیم داشت:

Please enter your input: SokanAcademy 123456 sokanacademy
SokanAcademy
123456

همان‌طور که مشاهده می‌کنیم، تعدادی کاراکتر و عدد وارد کرده سپس یک فاصله قرار داده‌ و در ادامه تعدادی کاراکتر دیگر وارد کرده‌‌ایم که بدین ترتیب با فراخوانی متد ()next استرینگ «SokanAcademy» تا قبل از اولین اِسپیس خوانده شده و با فراخوانی مجدد متد مذکور استرینگ «123456» مابین اولین اِسپیس تا پیش از اِسپیس بعدی نگهداری شده و در ادامه توسط متد ()println در کنسول چاپ می‌شوند. به علاوه، لازم به یادآوری است که به همین منوال می‌توان با فراخوانی متد ()next به تعداد دفعات مورد نیاز استرینگ‌های مد نظر را از ورودی خوانده و پردازش‌های مربوطه را روی دیتای ورودی انجام داد.

متد ()nextInt

متد ()nextInt از جمله دیگر متدهای پیش‌فرض در کلاس Scanner است که عملکردی مشابه متد ()next دارا است با این تفاوت که با به‌کارگیری متد ()nextInt صرفاً می‌توان یکسری عدد صحیح را از طریق کیبورد خوانده و در ادامه پردازش‌های مد نظر را روی آن‌ها اِعمال کرد. برای مثال، در کد زیر متد ()nextInt را فراخوانی کرده و نحوۀ عملکرد آن را مورد بررسی قرار می‌دهیم:

import java.util.Scanner;
public class ScannerClass {
    public static void main(String[] args) {
        Scanner keyboardInput = new Scanner(System.in);
        System.out.print("Please enter your input: ");
        System.out.println(keyboardInput.nextInt());
        keyboardInput.close();
    }
}

در کد فوق، مشابه مثال‌های پیشین، آبجکتی تحت عنوان keyboardInput از روی کلاس Scanner ساخته و در ادامه متد ()nextInt را روی آبجکت مذکور فراخوانی کرده‌ایم که نتیجۀ حاصل از این فراخوانی توسط متد ()println در کنسول نمایش داده می‌شود به طوری که در خروجی داریم: 

Please enter your input: 1000 2222 524836
1000

همان‌طور که پیش‌تر اشاره کردیم، متد ()nextInt مشابه ()next عمل کرده و تمامی دیتای ورودی از نوع عدد صحیح را تا پیش از اولین اِسپیس ذخیره می‌نماید که در ادامه دیتای مذکور توسط متد ()println در کنسول چاپ می‌گردد. نکتۀ قابل‌توجه در ارتباط با متد ()nextInt این است که متد مذکور صرفاً دیتای ورودی از نوع عدد صحیح را خوانده و وارد برنامه می‌کند. برای مثال، چنانچه داده‌ای از نوع عدد اعشاری را به عنوان ورودی به برنامه بدهیم خواهیم داشت:

Please enter your input: 12.5 2222 4569
Exception in thread "main" java.util.InputMismatchException
	at java.base/java.util.Scanner.throwFor(Scanner.java:939)
	at java.base/java.util.Scanner.next(Scanner.java:1594)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
	at ScannerClass.main(ScannerClass.java:6)

در واقع، فراخوانی متد ()nextInt به منظور ذخیره و نگهداری دیتایی همچون عدد 12/5 منجر به بروز خطا در روند اجرای برنامه شده است و ارور فوق حاکی از آن است که دادۀ ورودی با متد به کار گرفته شده هم‌خوانی ندارد.

متد ()nextDouble

متد ()nextDouble عملکردی مشابه متد ()nextInt دارا است با این تفاوت که به منظور ذخیرۀ نوع دادۀ عدد اعشاری از طریق کیبورد مورد استفاده قرار می‌گیرد که به عنوان مثال در کد زیر نحوۀ به‌کارگیری این متد را مورد بررسی قرار می‌دهیم:

import java.util.Scanner;
public class ScannerClass {
    public static void main(String[] args) {
        Scanner keyboardInput = new Scanner(System.in);
        System.out.print("Please enter your input: ");
        System.out.println(keyboardInput.nextDouble());
        keyboardInput.close();
    }
}

در کد فوق نیز، همچون مثال‌های پیشین، ابتدا آبجکتی تحت عنوان keyboardInput از روی کلاس Scanner ساخته و در ادامه آبجکت مذکور را روی متد ()nextDouble فراخوانی می‌نماییم که دیتای ریترن‌شده در نتیجۀ این فراخوانی با استفاده از متد ()println در کنسول نمایش داده می‌شود. بنابراین با اجرای برنامۀ فوق، در خروجی خواهیم داشت:

Please enter your input: 12.5 333 12566
12.5

همان‌طور که می‌بینیم، متد ()nextDouble دیتای ورودی مربوط به اعداد پیش از اولین اِسپیس را ذخیره کرده و دیتای مذکور با استفاده از متد ()println در کنسول چاپ شده است. نکتۀ قابل‌توجه در رابطه با متد ()nextDouble این است که بر خلاف متد ()nextInt قابلیت دریافت و ذخیرۀ اعداد صحیح را دارا است بدین معنی که نوع دادۀ عدد صحیح را در قالب یک عدد اعشاری ذخیره می‌کند. برای مثال، با اجرای مجدد کد فوق، عددی صحیح همچون 100 را در کنار سایر اعداد اعشاری به برنامه می‌دهیم:

Please enter your input: 100 25.5 69.3
100.0

در واقع، متد ()nextDouble عدد صحیح 100 را تا پیش از اولین اِسپیس دریافت کرده و در قالب یک عدد اعشاری ذخیره می‌کند که در ادامه این عدد توسط متد ()println در کنسول چاپ می‌گردد.

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



بهزاد مرادی

لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
jahani_zhr
jahani_zhr
۱۳۹۷/۰۶/۰۴
سلام
دومین برنامم رو هم نوشتم . مرسی از مطالب خوبتون. من ادامه میدم تا انشالله پیشرفت بهتری داشته باشم.
naderiforphone
naderiforphone
۱۳۹۷/۰۲/۲۳
با سلام. از آموزش شما خیلی استفاده بردم. فقط دو پرسش
اول: اگر در خط دوم فقط از عبارت ...class استفاده کنیم خطا می دهد که چنین کلاسی را نمی یابد. در نتیجه من قبل از آن public گذاشتم تا خطا برطرف شد.
دوم اینکه من دقیقا کد شما رو نوشتم و بارها چک کردم حتی کپی پیست کردم و مطمئنم که نادرست نیست اما وقتی پس از اجرا می نویسم mahdi naderi و سپس اینتر می زنم توقع این است که در خط بعد mahdi را چاپ کند. اما این عبارت می آید
ahdi di
naderi
دلیلش چیست؟ ممنون
monia_a56
monia_a56
۱۳۹۷/۰۱/۰۴
با سلام . ممنون تز آموزش عالیتون.
من تا اینحا بدون مشکل بودم. ولی در این درس دقیقا کدها رو کپی کردم و همه چی را وارد کردم. ولی بعد اجرا اروزیر رو دارم و چیزی هم نمیتونم وارد کنم .
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
scanner cannot be resolved to a type
کاربر میهمان
مهدیمن یک کاربر مهمان هستم
۱۳۹۵/۱۰/۲۴
سلام وقنی من myScanner رو میزنم ارور لامپ زرد رو میده کمک کنید به من
کاربر میهمان
محمدمن یک کاربر مهمان هستم
۱۳۹۵/۱۰/۱۰
عرض سلام و تشکر.
لطفا کد زیر رو در نظر بگیرید:
System.out.println(input.nextLine());
System.out.println(input.next());
System.out.println(input.nextLine());
System.out.println(input.nextLine());
لطفا توضیح بدید هنگام اجرای این کد چه اتفاقی می افته و چرا. ممنونم
کاربر میهمان
majidمن یک کاربر مهمان هستم
۱۳۹۵/۱۰/۰۴
سلام من چطور می تونم داده های که از وردی گرفتم رو تو یک متغییر دخیره کنم
Hossein94
Hossein94
۱۳۹۵/۰۵/۰۴
واقعا جالبه . ممنون از آموزشهاتون
Danyal
Danyal
۱۳۹۵/۰۴/۲۷
سلام من از متد next.Int در شرط if استفاد میکنم. دوبار ازم ورودی میگیره چرا؟
if(keyboardInput .nextInt==3) be in sorat
کاربر میهمان
حامدمن یک کاربر مهمان هستم
۱۳۹۵/۰۴/۲۱
سلام خداقوت
کارتون عالیه.مرسی
من میخوام یه برنامه بنویسم وزن رو به صورت ورودی دریافت کنه و وزن تو کره دیگه رو خروجی بده ،کدشو نوشتم ولی به مشکل خوردم میشه راهنمایی کنید
http://s6.picofile.com/file/8259360826/6.PNG
حسین
حسین
۱۳۹۴/۱۱/۰۱
فرض کنید یک کلمه وارد کنیم و اسپیس نزنیم
با این کد قاعدتا کامپایلر باید مقدار متغیر keyboarinput.next را دو بار نمایش دهد.

import java.util.Scanner;
class ScannerClass {
public static void main(String[] args) {
Scanner keyboardInput = new Scanner(System.in);
System.out.println(keyboardInput.next());
System.out.println(keyboardInput.next());
}
}
آیا بعد از نمایش جمله اول ، متغیر نول می شود؟