在一个字符串上处理成绩以获得最终成绩的程序

问题描述

Scanner scan = new Scanner(system.in);
        
        String num;
        
        String again = "yes";
        
        System.out.println("Welcome to the Grade Finalization Center");
        System.out.println("Want to continue?: ");
        String start = scan.nextLine();
        
        
            do {    
                // Start grade finalization // 
            
        System.out.println("Starting Program....");
        
        System.out.print("Student's name: ");
        String name = scan.next();
        
        System.out.println("Student's grades separated by space (A1 A2 EX P): ");
        num = scan.next();
        
        //String r1 = num.substring(0,2);
        //int r11 = Integer.parseInt(r1);
        //double A1 = (r11*0.25);
            
        String r2 = num.substring(3,4);
        //int r12 = Integer.parseInt(r1);
        //double A2 = (r12*0.25);
    
        System.out.println("Final grade is " + r2);
        
        
        
            
        
        System.out.print("Want to continue with another student?: ");
        again = scan.next();
        
        } while (again.equalsIgnoreCase("yes"));
            

出现错误

Exception in thread "main" java.lang.Stringindexoutofboundsexception: begin 3,end 4,length 2
    at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3734)
    at java.base/java.lang.String.substring(String.java:1903)
    at W4.main(W4.java:34)

解决方法

错误消息告诉您,您正在尝试访问不存在的字符串部分。您正在尝试从长度仅为 2 的字符串中获取位置 3-4,这显然是不可能的,因此将不起作用。

现在你的问题是:为什么在你调用的地方字符串 num 的长度只有 2

String r2 = num.substring(3,4);

您的问题是您如何尝试从用户输入中读取您的字符串:

 System.out.println("Student's grades separated by space (A1 A2 EX P): ");
 num = scan.next();

您显然希望用户输入包含空格的内容,但默认情况下,这不适用于 next()Scanner 方法。

我推荐阅读the official documentation of the scanner class you use

你会在类的描述中看到:

“扫描器使用分隔符模式将其输入分解为标记,默认情况下与空格匹配。”

在您使用的 next() 方法的文档中:

"从这个扫描器中查找并返回下一个完整的标记。一个完整的标记前后是匹配的输入 分隔符模式。”

这告诉您,默认情况下,方法 next() 只会读取输入,直到它到达第一个空格。 因此,目前如果您输入“A1 A2 EX P”,结果字符串将只是“A1”,因为到达分隔符并且 next() 方法认为它已经完成了它的工作。

您应该使用方法 next() 而不是 nextLine() 方法,以便您的输入能够包含空格。

,

实际上,我还没有完全理解你期望从结果中得到什么。 无论如何,让我们只关注导致异常的语句,特别是让我们看看以下几行:

System.out.println("Student's grades separated by space (A1 A2 EX P): ");
num = scan.next();
String r2 = num.substring(3,4);

简而言之,名为 r2 的 String 变量将被分配一个 num 的子字符串,该子字符串在前一行由标准输入中给出的值填充用户。 没关系,但是在使用方法 substring 时要小心。
定义如下:
public String substring(int beginIndex,int endIndex)
因此,该方法提取给定字符串的子字符串,这意味着它只是其中的一部分,从 beginIndex (在您的情况 3 中)开始,并以 endIndex 结束(在您的情况 4 ),其中第二个是“独占”,这意味着该索引处的字符不会包含在返回的字符串中。必须记住给定的字符串(即“num”)桅杆的长度至少等于 endIndex,否则它将始终抛出 StringIndexOutOfBoundsException,这意味着它已经超出了字符串。

因此,您的程序需要进行一些改进,以支持这些场景。

首先,我建议你用 scan.next() 替换所有的 scan.nextLine() 语句,这样你总是让程序读取用户插入的内容,直到他按下“Enter”,而方法 scan.next()只返回在字符串中找到的第一个标记,因为您使用了构造函数 Scanner(System.in),它将使用“默认”分隔符来匹配标记,即“空格”。
其次,如果你只是想得到用户写的最后一个成绩,你可以通过简单地使用以下语句来分配变量“r2”:

String r2 = !num.isEmpty() ? num.substring(num.length()-2,num.length()).trim() : "none";

您会注意到我还使用了一个三元运算符来包含用户未插入任何等级的情况,因此您可以打印出“none”。

试试这个,看看它是如何工作的。