簡體   English   中英

需要幫助修復我的代碼中的異常錯誤

[英]Need Help Fixing An Exception Error in my Code

我正在 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 會出現異常錯誤。 但是,當我在姓氏后添加一個空格時,代碼會按預期編譯。 出於評分目的,我需要在沒有鍵盤空格的情況下編譯代碼,因此我問我如何才能編譯此代碼。 我試過手動添加空格,但沒有任何效果。

任何幫助將不勝感激

查看代碼,很明顯您需要處理三 (3) 個特定的用戶輸入提示。 用戶必須提供名字,然后用戶需要提供中間名,最后用戶需要提供姓氏 與任何輸入一樣,這些名稱中的每一個都需要針對正確的上下文進行驗證。 這將包括姓名規則,例如每個人都有名字姓氏,但不是每個人都有中間名,名字和姓氏可以包含兩個名字詞(例如:De Vanderholt)。

當您有三個特定提示供用戶填寫時,請讓他們確切地知道他們在哪里。 在屏幕上顯示用戶期望輸入的內容。 將每個提示放入一個循環總是一個好主意,這樣輸入就可以被驗證,如果出現問題,用戶有機會提供實際的有效數據(在這種情況下是一個有效的名稱)。

在您的代碼中,您使用Scanner#next()方法來檢索名字中間名的輸入,但是由於next()方法是基於標記的,因此該方法不適用於多詞名稱。 這意味着,如果將兩個單詞的名稱提供給First Name提示,則僅檢索第一個單詞,而第二個單詞會自動應用於 Middle Name 提示。 你甚至沒有機會輸入中間名。 除非采用特殊代碼來解決這種情況,否則這是不好的。 在這種情況最好不要使用next()方法,而只需對所有提示使用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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM