Java:

2009-11-25 24 views
10

Aşağıdaki kodu kullanıyorum Tarayıcı in.hasNextInt() kullanarak Sonsuz döngü. Ben 'w' beni söyleyecektir "girdiniz geçersiz giriş girerseniz, AncakJava:

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."); 
    } 
} 

Tekrar Deneyin ." ve sonra, "0 ile 5 arasında bir tamsayı belirtin: Geçersiz bir girdi girdiniz. Tekrar deneyin." metnini gösteren sonsuz bir döngüye gidecektir.

neden oluyor?

if (in.hasNextInt()) 
+0

Kimin ne olduğunu veya nasıl inşa ettiğinizi hiç kimseye göstermediğinizden beri, nasıl davranması gerektiğini anlatamazsınız! –

cevap

13

, sen Scanner'dan 'w' veya diğer geçersiz giriş temizlemeniz gerekir. Aşağıdaki gibi, Tarayıcı üzerinde next() arayarak buralardan geçersiz giriş atmak için dönüş değerini göz ardı ederek bunu yapabilirsiniz:

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

Bayrak değişkenleri kullanmaya eğilimli de hata vardır: o ifadeyi eriştiğinde girmek girişine kullanıcı için bekleyip basın gerekiyordu programı değildir. Bunun yerine yorumlarla açık döngü kontrolünü kullanın. Ayrıca, hasNextInt() engellemez. Gelecekte bir next aramasının engellemeden girdi alıp alamayacağını görmek için engelleme dışı bırakma kontrolü. Engellemek istiyorsanız, nextInt() yöntemini kullanın. Son else bloğunda

// 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); 
+0

Tarayıcıyı sonlandırmanız için bir sebep var mı? – Tomek

+0

Bu kod hala sonsuz bir döngü üretir – Tomek

+0

Sonunu değiştirmeyeceğim için sonlandırıyorum. Derleyici bunun için belirli optimizasyonlar yapabilir. Final olabilecek her şeyi ilan etmek iyi bir alışkanlıktır. Kullanıcı doğru girişi girdiğinde döngü bozulur. Kullanıcı sınırsız yapmayı seçerse, sadece sonsuzdur. İsterseniz, yalnızca belirli sayıda yeniden deneme için izin verecek şekilde düzenleyebilirim. –

8

sorun sorunlu girişi geçmiş Scanner ilerletmek vermedi olmasıydı. hasNextInt() belgelerden;

İade true bu tarayıcının giriş sonraki belirteç nextInt() yöntemi kullanılarak varsayılan tabanda bir int değeri olarak yorumlanabilir eğer. Tarayıcı, herhangi bir girişi geçmiyor.

Bunların hepsi hasNextXXX() yöntemlerin doğrudur: onlar Scanner ilerleyen olmadan true veya false döner.

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! 
     } 
    } 

Bu program sürekli int, please! soran sonsuz bir döngüye girecektir olduğunu göreceksiniz:

İşte sorun göstermek için bir pasajı bu. Eğer sc.next() deyimi yorumsuz

, o zaman ScannerhasNextInt() başarısız belirteci ötesine geçmesini sağlayacaktır. Program daha sonra yazdırmak istiyoruz:

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

başarısız hasNextXXX() çek girişi atlamak olmadığı gerçeği kasıtlı şudur: Gerekirse o simge ek denetimler gerçekleştirmesini sağlar. İşte göstermek için bir örnek:

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()); 
     } 
    } 

Bu programı çalıştırırsanız, bu çıktıyı aşağıdaki edecektir: Ben S.

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

Bu açıklamadaBloke olmayan çağrı hakkında yanlış:

Ayrıca, hasNextInt() engellemez. Gelecekte yapılacak bir sonraki çağrının engellenmeden girdi elde edip edemeyeceğini görmek için engellenmeyen bir kontrol.

... Ben documentation kolayca bu fikir vermek için yanlış okumuş hususunu takdir yoktur ve adı kendisi bu amaçla kullanılacaksa ima rağmen. durularak, ilgili alıntı, eklendi:

sonraki() ve hasNext() yöntemleri ve ilk eşleşen herhangi girişi atlamak (örneğin nextInt() ve hasNextInt() gibi) kendi ilkel tip arkadaşı yöntemleri sınırlayıcı desen ve sonra bir sonraki belirteci döndürme girişiminde bulunun. Her ikisideNext ve sonraki yöntemler daha fazla giriş için beklemeyi engelleyebilir. Bir hasNext yönteminin, ilişkili sonraki yöntemin engellenip engellenmeyeceği ile ilgili bir bağlantının olup olmadığı.

Emin olmak için ince bir noktadır. "Hem hem hasNext hem de sonraki yöntemler" veya "Both hasnext() ve next()" deyimi, eşlik eden yöntemlerin farklı davranacağını ima ederdi. Fakat aynı isimlendirme kuralına (ve tabii ki belgelere) uyduklarını görmek, aynı davranmayı beklemek mantıklı ve hasNext() açıkça engelleyebileceğini söylüyor.

Meta not: Bu muhtemelen yanlış yazıya bir yorum olmalı, ancak yeni bir kullanıcı olarak bu cevabı yalnızca yayınlayabilirim (ya da kimyasal değişimler için değil, sytlistic değişikliklerde tercih edilen wikiyi düzenler)).