java的nextLine()的一个报错引发的思考

版权声明:本文为博主原创文章,未经允许,不得转载,如需转载请注明出处 https://blog.csdn.net/ssjdoudou/article/details/83987504

写在最前面:

晚上帮一位同学看一段代码,代码很入门,不过是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()就不会,因为遇到空格它就直接结束了。

猜你喜欢

转载自blog.csdn.net/ssjdoudou/article/details/83987504
今日推荐