2012-11-03 34 views
1

我有麻烦总结没有出现。我应该通过添加一组对象来修改以前的Java任务。在循环中,实例化每个单独的对象。确保用户无法继续添加超出数组大小的其他外部转换。 用户从菜单中选择退出后,提示用户是否要显示摘要报告。如果他们选择“Y”,那么,使用对象数组,显示以下报告:stringindexoutofbounds与货币换算的Java程序

Item  Conversion  Dollars  Amount 
1  Japanese Yen  100.00 32,000.00 
2  Mexican Peso  400.00 56,000.00 
3  Canadian Dollar 100.00  156.00 

转换次数= 3

有没有错误,当我编译..但是当我运行该程序时,直到我点击0结束转换并询问是否想要查看摘要才是正确的。此错误显示:

异常在线程 “主” java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:0 在java.lang.String.charAt(String.java:658) 在Lab8.main( Lab8.java:43)

我的代码:

import java.util.Scanner; 
import java.text.DecimalFormat; 

public class Lab8 
{ 
    public static void main(String[] args) 
    { 
     final int Max = 10; 
     String a; 
     char summary; 
     int c = 0; 
     Foreign[] Exchange = new Foreign[Max]; 
     Scanner Keyboard = new Scanner(System.in); 

     Foreign.opening(); 

     do 
     { 
     Exchange[c] = new Foreign(); 
      Exchange[c].getchoice(); 
     Exchange[c].dollars(); 
     Exchange[c].amount(); 
     Exchange[c].vertical(); 
     System.out.println("\n" + Exchange[c]); 
     c++; 

    System.out.println("\n" + "Please select 1 through 4, or 0 to quit" + >"\n"); 
     c= Keyboard.nextInt(); 

     } 
      while (c != 0); 


     System.out.print("\nWould you like a summary of your conversions? (Y/N): "); 
       a = Keyboard.nextLine(); 
       summary = a.charAt(0); 
       summary = Character.toUpperCase(summary); 

     if (summary == 'Y') 
       { 
     System.out.println("\nCountry\t\tRate\t\tDollars\t\tAmount"); 
       System.out.println("========\t\t=======\t\t=======\t\t========="); 
     for (int i=0; i < Exchange.length; i++) 
     System.out.println(Exchange[i]); 

      Foreign.counter(); 
      } 
    } 
} 

我看着线43和它的这一行:摘要= a.charAt(0);

但我不确定它有什么问题,任何人都可以指出它?谢谢。

+1

那么,你有什么尝试?显然,当你到达第43行时,字符串“a”是一个空字符串。你输入了一个空行吗? – Isaac

+0

?像刚刚按下输入? – mzzzzb

+0

只是对风格发表评论:我鼓励你遵循Java Code Coventions(http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html)......特别是:'thisIsararNameName '和'ThisIsAClassName' ...我也使'MAX_EXCHANGES'常量而不是本地'Max'变量。 – corlettk

回答

1

问题并不完全在于那条线,而是以前一段时间的最后一行。 您在使用int阅读: -

c= Keyboard.nextInt(); 

如果你看到Scanner#nextInt方法的文档,它读取用户输入的下一个标记。

a = Keyboard.nextLine(); 

后 - :所以,当你传递一个整数值,那么linefeed末也被你压enter而传递不被Keyboard.nextInt读,然后将其剩余通过阅读while退出。所以,基本上这条语句是通过预先拨号Keyboard.nextInt读取左边的换行符,因此a包含一个empty字符串,最后是newline。因此你得到那个Exception

解决方法: -

您可以触发这个说法,这将消耗linefeed作为其输入,让你的下一个用户输入后,它开始前一个空Keyboard.nextLine

// Your code before this while 
} while (c != 0); 

Keyboard.nextLine(); // Add this line before the next line 

System.out.print("\nWould you like a summary of your conversions? (Y/N): "); 
a = Keyboard.nextLine(); 

或者,另一种方式是,您可以使用Keyboard.nextLine还需要阅读整数值。然后使用Integer.parseInt方法将其转换为整数。但要小心,你将不得不做一些异常处理。所以如果你仍然要学习Exception Handling,那么你可以用第一种方式去。所以,你的do-while里面,你可以做这样的: -

try { 
    c = Integer.parseInt(Keyboard.nextLine()); 
} catch (NumberFormatException e) { 
    e.printStackTrace(); 
} 
+0

+1“不要使用nextInt()”......根据我的经验,整个Scanner类是无用的一块垃圾,你最好只使用BufferedReader。 – corlettk

+0

@corlettk。如果你不想用你的输入做任何解析,那么BufferedReader会更好,但只要阅读它。但是如果你想做某种解析,那么Scanner会给你更好的功能。 –

+0

我的观点是,扫描仪为您提供了更多(但不是更好)的功能,所以到实际生产使用扫描仪的“可用产品”时,您可以轻松使用基本的BufferedReader。如果您对我的意思是“可用”感兴趣,请参阅下面的答案...我的控制台类可以避免标准扫描程序类的大部分“使用缺陷”,而且它不是很多代码......特别是当它可以重用时...我在需要从命令行应用程序中读取键盘输入的地方使用它。 – corlettk

1

这是常见的问题。当您使用c= Keyboard.nextInt();时,它会读取int。如果在此语句中按回车键,则a = Keyboard.nextLine();将从输入缓冲区中的前一个语句读取一个空字符串作为子缓冲区。

你有两个选择:

  1. 添加额外的Keyboard.nextLine();清理读缓冲区a作为a = Keyboard.nextLine();

  2. 之前,如果你想让它充分证明,以避免在读空行的问题(使用按回车键没有输入日期)然后把一个while循环如下:

    a = ""; 
    while(a.length() <1){ 
        a = Keyboard.nextLine(); 
    } 
    

    这将确保astring length >1,当它出现循环。有了真正的输入,它不会做任何迭代。

+0

好的答案,尤其是重新读取空字符串的循环...除非该循环应该(恕我直言)包含错误信息(类似“无效的输入,请再试一次...”)。否则,用户可能认为软件不在那里读取输入,当实际情况是输入不能被处理时,因为它是无效的。 – corlettk

0

这是我的控制台类,我用它代替扫描仪在命令行应用程序中读取键盘输入。请注意,类“包装”了Java 1.6中引入的标准java.io.Console。

你可以从我的控制台类中挖掘出你需要的方法,将它们直接放在你的Lab8类中......但是我鼓励你尽早习惯于将不同类的“分离问题”自己的“键盘”类,作为我的控制台的精简版。

package krc.utilz.io; 

import java.util.Date; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 


/** 
* A static library of helper methods to read keyboard input. 
* <p> 
* <strong>usage:</strong> 
* <code> 
* import krc.utilz.io.Console; 
* while ((score=Console.readInteger("Enter an integer between 0 and 100 (enter to exit) : ", 0, 100, -1)) != -1) { ... } 
* </code> 
*/ 
public abstract class Console 
{ 
    private static final java.io.Console theConsole = System.console(); 
    static { 
    if (theConsole == null) { 
     System.err.println("krc.utilz.io.Console: No system console!"); 
     System.exit(2); // 2 traditionally means "system error" on unix. 
    } 
    } 
    private static final DateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy"); 
    private static final DateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss"); 

    public static String readString(String prompt) { 
    String response = readLine(prompt); 
    if(response==null) throw new NullPointerException("response cannot be null"); 
    return response; 
    } 

    public static String readLine(String prompt) { 
    if (!prompt.endsWith(" ")) prompt += " "; 
    System.out.print(prompt); 
    return theConsole.readLine(); 
    } 

    public static String readString(String prompt, String regex) { 
    while(true) { 
     String response = readString(prompt); 
     if (response.length() > 0) { 
     if (response.matches(regex)) { 
      return response; 
     } 
     } 
     System.out.println("Oops: A match for "+regex+" is required!"); 
    } 
    } 


    public static Date readDate(String prompt) { 
    while(true) { 
     try { 
     return dateFormatter.parse(readString(prompt+" (dd/MM/yyyy) : ")); 
     } catch (java.text.ParseException e) { 
     System.out.println("Oops: "+e); 
     } 
    } 
    } 

    public static Date readTime(String prompt) { 
    while(true) { 
     try { 
     String response = readWord(prompt+" (HH:mm:ss) : "); 
     return timeFormatter.parse(response); 
     } catch (java.text.ParseException e) { 
     System.out.println("Oops: "+e); 
     } 
    } 
    } 

    public static String readWord(String prompt) { 
    while(true) { 
     String response = readString(prompt); 
     if(response.length()>0 && response.indexOf(' ')<0) return response; 
     System.out.println("Oops: A single word is required. No spaces."); 
    } 
    } 

    public static String readWordOrNull(String prompt) { 
    while(true) { 
     String response = readLine(prompt); 
     if(response==null||response.length()==0) return null; 
     if(response.indexOf(' ')<0) return response; 
     System.out.println("Oops: A single word is required. No spaces."); 
    } 
    } 

    public static char readChar(String prompt) { 
    while (true) { 
     String response = readString(prompt); 
     if (response.trim().length() == 1) { 
     return response.trim().charAt(0); 
     } 
     System.out.println("Oops: A single non-whitespace character is required!"); 
    } 
    } 

    public static char readLetter(String prompt) { 
    while(true) { 
     String response = readString(prompt); 
     if (response.trim().length() == 1) { 
     char result = response.trim().charAt(0); 
     if(Character.isLetter(result)) return result; 
     } 
     System.out.println("Oops: A single letter is required!"); 
    } 
    } 

    public static char readDigit(String prompt) { 
    while(true) { 
     String response = readString(prompt); 
     if (response.trim().length() == 1) { 
     char result = response.trim().charAt(0); 
     if(Character.isDigit(result)) return result; 
     } 
     System.out.println("Oops: A single digit is required!"); 
    } 
    } 

    public static int readInteger(String prompt) { 
    String response = null; 
    while(true) { 
     try { 
     response = readString(prompt); 
     if (response.length()>0) { 
      return Integer.parseInt(response); 
     } 
     System.out.println("An integer is required."); 
     } catch (NumberFormatException e) { 
     System.out.println("Oops \""+response+"\" cannot be interpreted as 32-bit signed integer!"); 
     } 
    } 
    } 

    public static int readInteger(String prompt, int lowerBound, int upperBound) { 
    int result = 0; 
    while(true) { 
     result = readInteger(prompt); 
     if (result>=lowerBound && result<=upperBound) break; 
     System.out.println("An integer between "+lowerBound+" and "+upperBound+" (inclusive) is required."); 
    } 
    return(result); 
    } 

    public static int readInteger(String prompt, int defaultValue) { 
    String response = null; 
    while(true) { 
     try { 
     response = readString(prompt); 
     return response.trim().length()>0 ? Integer.parseInt(response) : defaultValue; 
     } catch (NumberFormatException e) { 
     System.out.println("Oops \""+response+"\" cannot be interpreted as 32-bit signed integer!"); 
     } 
    } 
    } 

    public static int readInteger(String prompt, int lowerBound, int upperBound, int defaultValue) { 
    int result = 0; 
    while(true) { 
     result = readInteger(prompt, defaultValue); 
     if (result==defaultValue || result>=lowerBound && result<=upperBound) break; 
     System.out.println("An integer between "+lowerBound+" and "+upperBound+" (inclusive) is required."); 
    } 
    return(result); 
    } 

    public static double readDouble(String fmt, Object... args) { 
    String response = null; 
    while(true) { 
     try { 
     response = System.console().readLine(fmt, args); 
     if (response!=null && response.length()>0) { 
      return Double.parseDouble(response); 
     } 
     System.out.println("A number is required."); 
     } catch (NumberFormatException e) { 
     System.out.println("\""+response+"\" cannot be interpreted as a number!"); 
     } 
    } 
    } 

    public static double readDouble(String prompt, double lowerBound, double upperBound) { 
    while(true) { 
     double result = readDouble(prompt); 
     if (result>=lowerBound && result<=upperBound) { 
     return(result); 
     } 
     System.out.println("A number between "+lowerBound+" and "+upperBound+" (inclusive) is required."); 
    } 
    } 

    public static boolean readBoolean(String prompt) { 
    String response = readString(prompt+" (y/N) : "); 
    return response.trim().equalsIgnoreCase("Y"); 
    } 

    public static java.io.Console systemConsole() { 
    return theConsole; 
    } 

} 

干杯。基思。

PS:这会让练习变得更容易......你现在很好......只要继续练习。

+0

谢谢大家的好的答案,它帮助了我很多,我学到的不仅仅是解决问题的方法。我的程序现在效果很好!哦,基思,谢谢你发布一些很好的学习材料,尤其是像我这样的新手! – LittleMissTrouble