写在最前面:
晚上帮一位同学看一段代码,代码很入门,不过是java的,还好我也是懂java的男人,哼哼
代码如下,我做了一点调整,方便看输出:
package Arithmetic;
import java.util.Scanner;
class PayCheck
{
public static void main(String args[])
{
//user's input
Scanner kbReader = new Scanner (System.in);
String famName;
String givName;
double ratePay;
int workHour;
char charity;
char tax;
System.out.println("What is your family name?");
famName = kbReader.nextLine();
System.out.println("What is your given name?");
givName = kbReader.nextLine();
System.out.println("What is your hourly rate of pay($/h)?");
ratePay = kbReader.nextDouble();
System.out.println("How many hours you have worked this week?");
workHour= kbReader.nextInt();
System.out.println("Do you want $20 deducted from the weekly pay as a contribution to chairty? Enter Y for yes and N for no.?");
charity = kbReader.nextLine().charAt(0);
System.out.println("What's your tax category?(choose from A to E.)");
tax = kbReader.nextLine().charAt(0);
//processing
//Gross Pay
double grossPay;
if (workHour<=40)
{
grossPay=workHour*ratePay;
}
else
{
grossPay=40*ratePay+(workHour-40)*ratePay*2;
}
//Charity
if (charity=='Y')
grossPay=grossPay-20;
else if(charity=='N')
grossPay=grossPay-0;
//Deduction
double dedu;
if (tax=='A')
dedu=0;
else if (tax=='B')
dedu=grossPay*0.1;
else if(tax=='C')
dedu=grossPay*0.2;
else if(tax=='D')
dedu=grossPay*0.29;
else
dedu=grossPay*0.35;
//net pay
double netPay;
netPay=grossPay-dedu;
//output
System.out.println("Weekly Pay Slip");
System.out.println(famName+givName);
System.out.println("Gross Pay: /$"+grossPay);
System.out.println("Deductions: /$"+dedu);
System.out.println("Net Pay: /$"+netPay);
}
}
这个有啥问题呢?
What is your family name?
A
What is your given name?
B
What is your hourly rate of pay($/h)?
12
How many hours you have worked this week?
6
Do you want $20 deducted from the weekly pay as a contribution to chairty? Enter Y for yes and N for no.?
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at Arithmetic.PayCheck.main(PayCheck.java:25)
那么很显然了,第一个出错的是这一行(不代表后面的没问题)
charity = kbReader.nextLine().charAt(0);
我们在之前定义了一个
char charity;
由于java中没有提供方法直接从键盘接收一个字符,但是我们可以用从键盘接收一个字符串实现接收一个字符的功能,就是接收字符串中第一个字符。
但是这个和报错有什么关系呢,明明思路没问题啊。
当我们尝试改成:
charity = kbReader.next().charAt(0);
就OK了
Do you want $20 deducted from the weekly pay as a contribution to chairty? Enter Y for yes and N for no.?
uu
u
那么next()和nextLine()有什么区别呢?
next()方法在读取内容时,会过滤掉有效字符前面的无效字符,对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其过滤掉;只有在读取到有效字符之后,next()方法才将其后的空格键、Tab键或Enter键等视为结束符;所以next()方法不能得到带空格的字符串。
nextLine()方法返回的是Enter键之前没有被读取的所有字符,它是可以得到带空格的字符串的
一句话,next()方法读取到空白符就结束,nextLine()读取到回车结束也就是“\r”。
那么当我们试图用nextLine()读取字符串的第一个字符时,由于我们还没有输入,意味着输入会是一个空字符串,而空字符串的长度是0,charAt(0)时,一定会超长。
java.lang.String.charAt() 方法返回指定索引处的char值。索引范围是从0到length() – 1。对于数组索引,序列的第一个char值是在索引为0,索引1,依此类推。
当我们debug看的时候了,代码如下:
System.out.println("Do you want $20 deducted from the weekly pay as a contribution to chairty? Enter Y for yes and N for no.?");
try {
System.out.println("".charAt(0));
charity = kbReader.nextLine().charAt(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
在这一句上加断点:
System.out.println("".charAt(0));
如图所示:
我们试图打印空字符串的第一个字符,由于charAt()的定义是0到length()-1,那么此时索引超长,直接抛出异常。
而next()就不会,因为遇到空格它就直接结束了。