【问题标题】:Need Help Fixing An Exception Error in my Code需要帮助修复我的代码中的异常错误
【发布时间】:2021-01-27 00:56:50
【问题描述】:

我正在 Zybooks 网站上的实验室工作,我已完成以下代码:

import java.util.Scanner; 

public class LabProgram {
public static void main(String[] args) {
    Scanner scnr = new Scanner(System.in);

    String firstName;
    String middleName;
    String lastName;

    firstName = scnr.next();
    middleName = scnr.next();
    lastName = scnr.nextLine();
   

    if (lastName.contains("")){
        System.out.println(middleName + ", " + firstName.charAt(0) + ".");
    }
    else {
        lastName = lastName.substring(1);
        System.out.println(lastName + ", " + firstName.charAt(0) + "." + middleName.charAt(0) + ".");
    }
  }
  }

我收到的异常错误是这样的:

Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at LabProgram.main(LabProgram.java:13)

当我在 IDE 中运行以下代码时,一切正常。但是,当我尝试在 Zybooks 中运行它时,出现异常错误。我了解到这是因为当我在输入两个名称后不添加空格时,Zybooks 会出现异常错误。但是,当我在姓氏后添加一个空格时,代码会按预期编译。出于评分目的,我需要在没有键盘空格的情况下编译代码,因此我在问如何才能编译此代码。我试过手动添加空格,但没有任何效果。

任何帮助将不胜感激

【问题讨论】:

    标签: java debugging error-handling compiler-errors runtime-error


    【解决方案1】:

    查看代码很明显,您需要处理三 (3) 个特定的用户输入提示。用户必须提供 First Name,然后用户需要提供 Middle Name,最后用户需要提供 Last Name .与任何输入一样,这些名称中的每一个都需要针对正确的上下文进行验证。这将包括姓名规则,例如,每个人都有一个First NameLast Name,但不是每个人都有一个Middle Name同时也是第一个和最后一个名称可以包含两个名称词(例如:De Vanderholt)。

    当您需要用户填写三个特定提示时,请让他们确切地知道他们在哪里。在屏幕上显示用户预期输入的内容。将每个提示放入一个循环中总是一个好主意,这样可以验证输入,如果有问题,用户有机会提供实际的有效数据(在这种情况下是一个有效的名称)。

    在您的代码中,您使用 Scanner#next() 方法来检索 First NameMiddle Name(s) 的输入,但是此方法不适用于 multi单词名称,因为 next() 方法是基于标记的。这意味着,如果向 First Name 提示提供了两个单词的名称,则只会检索第一个单词,而第二个单词会自动应用于 Middle Name 提示。你甚至没有机会输入中间名。除非设置特殊代码来处理这种情况,否则这是不好的。在这种情况下,最好不要使用 next() 方法,而只需对 all 提示使用 Scanner#nextLine() 方法。但是请记住,如果您知道用户只会提供一个名称单词,Scanner#next() 方法将可以正常工作,但此方法最好与 Scanner#hasNext() 方法结合使用。

    查看您的代码。如前所述,每个人都有一个姓氏,但不是每个人都有一个中间名,那么为什么要有这行代码(除非您的规则包括姓氏可以是什么):

     if (lastName.contains("")){
    

    实际上不应该允许出现姓氏不包含任何内容的情况,甚至不要接受这个事实,除非它是中间名。如果提供的姓氏经过验证,那么您将永远不必担心这种情况,除非您的规则当然允许。下面的示例代码不允许这样做。

    因为有三个提示,它们基本上做同样的事情并需要相同的基本验证,所以使用辅助方法(getName())来消除重复代码的需要:

    public static void main(String[] args) {
        Scanner scnr = new Scanner(System.in);
         
        // First Name:
        String firstName = getName(scnr, "First");
        
        // Middle Name:
        String middleName = getName(scnr, "Middle");
    
        // Last Name:
        String lastName = getName(scnr, "Last");
    
        System.out.println(new StringBuilder("")
                .append(lastName).append(", ")
                .append(firstName.charAt(0))
                .append(". ")
                .append(middleName.isEmpty() ? "" : middleName.charAt(0))
                .append(middleName.isEmpty() ? "" : ".").toString());
    
        //                    O R
        /*
        System.out.println(new StringBuilder("")
                           .append(lastName).append(", ")
                           .append(firstName)
                           .append(" ")
                           .append(middleName)
                           .toString());
        */
        //                    O R
        /*
        System.out.println(new StringBuilder("")
                           .append(firstName)
                           .append(" ")
                           .append(middleName)
                           .append(middleName.isEmpty() ? "" : " ")
                           .append(lastName)
                           .toString());
         */
    }
    

    辅助方法(getName()):

    private static String getName(final Scanner scnr, final String nameTitle) {
        String name = "";
        while (name.isEmpty()) {
            System.out.print("Enter your " + nameTitle + " Name: --> ");
            // Get input and trim off leading/trailing whitespaces, etc 
            name = scnr.nextLine().trim();
            // Is this for a Middle Name?
            if (nameTitle.equalsIgnoreCase("middle")) {
                // If nothing was supplied then there is no 
                // middle name so break out of prompt loop.
                if (name.isEmpty()) {
                    break;
                }
            }
            // Validate name...
            /* Does the supplied name only contain A to Z characters 
               in any letter case. Add characters to the regular 
               expression as you see fit. (?i) means any letter case. */
            if (name.matches("(?i)[A-Z. ]+")) {
                // Yes, it does...
                /* Ensure 'first' character of each name word (if more than one) 
                   is upper letter case.       */
                String[] tmp = name.split("\\s+");
                StringBuilder nme = new StringBuilder("");
                for (String str : tmp) {
                    if (!Character.isUpperCase(str.charAt(0))) {
                        str = str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
                    }
                    if (!nme.toString().isEmpty()) {
                        nme.append(" ");
                    }
                    nme.append(str);
                }
                name = nme.toString();
            }
            // No it doesn't so inform User of the mistake and to try again.
            else {
                System.err.println("Invalid " + nameTitle + " Name Supplied! (" + name + ") Try Again...");
                name = ""; // Set to null string so as to re-prompt.
            }
        }
        return name;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-10-30
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      相关资源
      最近更新 更多