java - 需要帮助修复我的代码中的异常错误
问题描述
我正在 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;
}
推荐阅读
- python - 在 Linux 服务器上使用 Python Flask 的 Nginx 400 错误请求
- python - Fin plot 安装和导入问题
- javascript - 如果另一个 div 高度溢出,则显示/隐藏按钮
- php - 如何允许访问多站点上的 wordpress 插件 php 文件
- c++ - 在 C++ 中合并排序数组的问题
- c++ - !temp->left 和 temp->left!=NULL 不同吗?
- reactjs - ReactJS 定位组件
- sublimetext - sublime 插件开发区域相交
- c# - 更好的方法来编码 HTML 字符串中的所有小于 (<) 字符,而不是 HTML 标记
- ethereum - 在地址支付 [] 存储参考中进行参数相关查找后,成员“推送”未找到或不可见