2011-01-16 34 views
11

L'esecuzione del seguente in Eclipse inizialmente causato scanner di non riconoscere ritorni a capo nella console che bloccano efficacemente ulteriore input:comportamento strano con scanner # nextFloat

price = sc.nextFloat(); 

Aggiungendo questa riga prima del codice provoca scanner ad accettare 0,23 (notazione francese) come float:

Locale.setDefault(Locale.US); 

Questo è molto probabilmente a causa di impostazioni internazionali di Windows XP Pro (francese/belga). Quando il codice viene eseguito di nuovo, 0,23 viene ancora accettato e l'immissione di 0,23 provoca il lancio di un numero java.util.InputMismatchException.

Qualche spiegazione sul perché questo sta accadendo? C'è anche una soluzione alternativa o dovrei semplicemente usare Float#parseFloat?

Modifica: questo dimostra come si comporta lo Scanner con diverse impostazioni locali (decommentare una delle righe all'inizio).

import java.util.Locale; 
import java.util.Scanner; 


public class NexFloatTest { 

    public static void main(String[] args) { 

     //Locale.setDefault(Locale.US); 
     //Locale.setDefault(Locale.FRANCE); 

     // Gives fr_BE on this system 
     System.out.println(Locale.getDefault()); 

     float price; 

     String uSDecimal = "0.23"; 
     String frenchDecimal = "0,23"; 

     Scanner sc = new Scanner(uSDecimal); 

     try{ 
      price = sc.nextFloat(); 
      System.out.println(price); 
     } catch (java.util.InputMismatchException e){ 
      e.printStackTrace(); 
     } 

     try{ 
      sc = new Scanner(frenchDecimal); 
      price = sc.nextFloat(); 
      System.out.println(price); 
     } catch (java.util.InputMismatchException e){ 
      e.printStackTrace(); 
     } 

     System.out.println("Switching Scanner to System.in"); 

     try{ 
      sc = new Scanner(System.in); 
      System.out.println("Enter a float value"); 
      price = sc.nextFloat(); 
      System.out.println(price); 
     } catch (java.util.InputMismatchException e){ 
      e.printStackTrace(); 
     } 

     System.out.print("Enter title:"); 

     String title = sc.nextLine(); // This line is skipped 

     System.out.print(title); 
    } 

} 

Edit: questo riproduce il problema in cui lo scanner è in attesa di un valore float, ma non riesce a innescare quando si preme ritorno:

import java.util.Scanner; 

public class IgnoreCRTest { 

    public static void main(String[] args) { 
     Scanner sc = new Scanner(System.in); 
     System.out.println("Enter a float value:"); 
     // On french Locale use , as the decimal separator 
     float testFloat = sc.nextFloat(); 
     System.out.println(testFloat); 
     //sc.skip("\n"); // This doesn't solve the issue 
     sc.nextLine(); 
     System.out.println("Enter an integer value:"); 
     int testInt = sc.nextInt(); 
     System.out.println(testInt); 
     // Will either block or skip here 
     System.out.println("Enter a string value :"); 
     String testString = sc.nextLine(); 
     System.out.println(testString); 
    } 

} 
+3

Puoi fornire un esempio eseguibile che mostri il sequestro effettivo del codice in esecuzione e che manifesti il ​​problema? –

+0

Sicuro. Aggiungerò del codice in pochi minuti. –

risposta

13

Mi chiedo se non stai gestione di una chiusura della linea token appropriatamente. Spesso se usi Scanner # # ###() (eccetto per nextLine), e raggiungi un token di fine riga come quando l'utente preme Invio, se non gestisci il token di fine riga, impedirà lo Scanner oggetto dal lavorare in modo appropriato. Per risolvere questo problema, chiama Scanner # nextLine() quando questo token deve essere gestito. Se pubblichi parte del tuo codice, possiamo vedere se questo è davvero il tuo problema e se il mio suggerimento offre una soluzione.

modifica: no, non stai utilizzando System.in quindi non è questo il problema. D'altra parte, è necessario impostare le impostazioni locali dello scanner prima di accettare il numero francese. Ad esempio,

 sc = new Scanner(frenchDecimal); 
    sc.useLocale(Locale.FRENCH); 
    price = sc.nextFloat(); 
+3

se non si chiama useLocale (...) lo Scanner verrà costruito con le impostazioni internazionali predefinite. Le impostazioni internazionali predefinite dell'OP sono francesi. –

+1

Grazie per la risposta, ma mi dispiace per averlo perso. Dove dichiara che il locale predefinito è il francese? –

+0

Grazie. L'impostazione delle impostazioni internazionali per lo scanner fa il trucco (volevo usare il decimale americano). Qualche idea su cosa sta causando la prossima riga da saltare nel codice modificato? Inoltre, poiché era impostato Locale, non sono stato in grado di riprodurre il problema in cui lo scanner sembra accettare il testo ma non riconosce i ritorni a capo. –