جافا: حلقة لا نهائية باستخدام الماسح الضوئي في. hasnextint ()

StackOverflow https://stackoverflow.com/questions/1794281

سؤال

أنا أستخدم الكود التالي:

while (invalidInput)
{
    // ask the user to specify a number to update the times by
    System.out.print("Specify an integer between 0 and 5: ");

    if (in.hasNextInt())
    {
        // get the update value
        updateValue = in.nextInt();

        // check to see if it was within range
        if (updateValue >= 0 && updateValue <= 5) 
        { 
            invalidInput = false; 
        } 
        else 
        {
            System.out.println("You have not entered a number between 0 and 5. Try again.");
        }
    } else
    {
        System.out.println("You have entered an invalid input. Try again.");
    }
}

ومع ذلك ، إذا أدخلت "W" ، فسيخبرني "لقد أدخلت إدخالًا غير صالح. حاول مرة أخرى." وبعد ذلك سوف يذهب إلى حلقة لا حصر لها توضح النص "حدد عدد صحيح بين 0 و 5: لقد أدخلت إدخالًا غير صالح. حاول مرة أخرى."

لماذا يحدث هذا؟ ليس من المفترض أن ينتظر البرنامج حتى يقوم المستخدم بإدخاله واضغط على إدخال في كل مرة يصل فيها إلى العبارة:

if (in.hasNextInt())
هل كانت مفيدة؟

المحلول

في آخر مرة else كتلة ، تحتاج إلى مسح "W" أو أي مدخلات غير صالحة أخرى من الماسح الضوئي. يمكنك القيام بذلك عن طريق الاتصال next() على الماسح الضوئي وتجاهل قيمة الإرجاع الخاصة به لرمي هذه الإدخال غير الصالح ، على النحو التالي:

else
{
      System.out.println("You have entered an invalid input. Try again.");
      in.next();
}

نصائح أخرى

كانت المشكلة أنك لم تقدم Scanner بعد المدخلات الإشكالية. من عند hasNextInt() توثيق:

عائدات true إذا كان يمكن تفسير الرمز المميز التالي في مدخلات هذا الماسح الضوئي على أنه int القيمة في الدعامة الافتراضية باستخدام nextInt() طريقة. الماسح الضوئي لا يتقدم بعد أي مدخلات.

هذا صحيح للجميع hasNextXXX() الطرق: يعودون true أو false, ، دون التقدم Scanner.

إليك مقتطف لتوضيح المشكلة:

    String input = "1 2 3 oops 4 5 6";
    Scanner sc = new Scanner(input);
    while (sc.hasNext()) {
        if (sc.hasNextInt()) {
            int num = sc.nextInt();
            System.out.println("Got " + num);
        } else {
            System.out.println("int, please!");
            //sc.next(); // uncomment to fix!
        }
    }

ستجد أن هذا البرنامج سيذهب إلى حلقة لا حصر int, please! مرارا وتكرارا.

إذا قمت بتفكيك sc.next() البيان ، ثم سوف يصنع Scanner تجاوز الرمز المميز الذي يفشل hasNextInt(). ثم يطبع البرنامج:

Got 1
Got 2
Got 3
int, please!
Got 4
Got 5
Got 6

حقيقة أن الفشل hasNextXXX() لا تتخطى الإدخال عن قصد: فهو يتيح لك إجراء فحوصات إضافية على هذا الرمز المميز إذا لزم الأمر. إليك مثال لتوضيح:

    String input = " 1 true foo 2 false bar 3 ";
    Scanner sc = new Scanner(input);
    while (sc.hasNext()) {
        if (sc.hasNextInt()) {
            System.out.println("(int) " + sc.nextInt());
        } else if (sc.hasNextBoolean()) {
            System.out.println("(boolean) " + sc.nextBoolean());
        } else {
            System.out.println(sc.next());
        }
    }

إذا قمت بتشغيل هذا البرنامج ، فسيتم إخراج ما يلي:

(int) 1
(boolean) true
foo
(int) 2
(boolean) false
bar
(int) 3

هذا البيان الذي كتبه بن س. حول مكالمة عدم الحظر خاطئة:

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

... على الرغم من أنني أدرك أن توثيق يمكن بسهولة أن يتم القراءة لإعطاء هذا الرأي ، والاسم نفسه يعني أنه يجب استخدامه لهذا الغرض. الاقتباس ذي الصلة ، مع التركيز:

طرق NEXT () و HASNEXT () وأساليبها المصاحبة من النوع البدائي (مثل NextInt () و hasnextint ()) أولاً ، تخطي أي إدخال يطابق نمط المحدد ، ثم حاول إعادة الرمز المميز التالي. كل من Hasnext والطرق التالية قد تمنع في انتظار مزيد من المدخلات. ما إذا كانت مجموعة طريقة HasNext لا تصل إلى ما إذا كانت الطريقة التالية المرتبطة بها ستحظر أم لا.

إنها نقطة خفية ، بالتأكيد. إما أن يقول "كلاهما ال كان من المفترض أن تتصرف الأساليب المصاحبة بشكل مختلف. أو "كلاهما hasnext () و Next ()" نتوقع أن يتصرفوا كما هو ، و hasnext ()يقول بوضوح أنه يمكن أن يمنع.

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

متغيرات العلم هي خطأ معرضة للاستخدام. استخدم التحكم الصريح مع التعليقات بدلاً من ذلك. ايضا، hasNextInt() لا يمنع. إنه الشيك غير المحظور لمعرفة ما إذا كان المستقبل next يمكن أن تحصل المكالمة على الإدخال دون حظر. إذا كنت تريد حظر ، استخدم nextInt() طريقة.

// Scanner that will read the integer
final Scanner in = new Scanner(System.in);
int inputInt;
do {  // Loop until we have correct input
    System.out.print("Specify an integer between 0 and 5: ");
    try {
        inputInt = in.nextInt(); // Blocks for user input
        if (inputInt >= 0 && inputInt <= 5)  { 
            break;    // Got valid input, stop looping
        } else {
            System.out.println("You have not entered a number between 0 and 5. Try again.");
            continue; // restart loop, wrong number
         }
    } catch (final InputMismatchException e) {
        System.out.println("You have entered an invalid input. Try again.");
        in.next();    // discard non-int input
        continue;     // restart loop, didn't get an integer input
    }
} while (true);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top