问题描述
我正在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会给出异常错误。但是,当我在姓氏后面添加空格时,代码将按预期编译。出于评分的目的,我需要在没有键盘空格的情况下编译代码,因此我在问如何获取此代码。我尝试手动添加空格,但没有任何效果。
任何帮助将不胜感激
解决方法
<?php
namespace App\Jobs;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Model\BccMapping;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessUnmappedRequests implements ShouldQueue
{
use Dispatchable,InteractsWithQueue,Queueable,SerializesModels;
protected $request;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($id,$request)
{
$this->siteId = $request->get('siteId');
$this->mappingId = $request->get('mappingId');
$this->email = $request->get('originEmail');
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$unmappedRequests = DB::table('bcc')->where("EmailFrom",trim($this->email))->whereNull('BccMappingId')
->where('Archive',0)->get();
if($unmappedRequests->isNotEmpty()){
$mapping = BccMapping::where('id',$this->mappingId )->first();
if(!$mapping)
return false;
$mappingData = json_decode($mapping->mapping);
$keyword = $mapping->keyword;
foreach ($unmappedRequests as $key=>$bcc){
$bccKeyword = app('App\Http\Controllers\BccToolController')->getDomNodeValue($mappingData->keywordPath->path,$bcc->HTML);
var_dump($bccKeyword);die;
}
}else{
return false;
}
}
}
时,通常会在扫描程序的上下文中引发 java.util.NoSuchElementException
,并且没有下一行。您可以在提出要求之前先检查下一行内容。
尝试如下代码:
nextLine()
,
看代码,您显然有三(3)个特定的用户输入提示要处理。用户必须提供名,然后用户需要提供中间名,最后用户需要提供姓氏 。与任何输入一样,这些名称中的每一个都需要针对适当的上下文进行验证。这将包括名称规则,例如每个人都有一个名字和姓氏,但不是每个人都有一个中间名名称可以包含两个名称词(例如:De Vanderholt)。
当您有三个要用户填写的特定提示时,请让他们确切知道他们的位置。在屏幕上显示预期用户输入的内容。将每个提示放入循环中始终是一个好主意,以便可以验证输入,如果出现问题,则可以给用户提供实际有效数据(在这种情况下为有效名称)的机会。
在代码中,您使用Scanner#next()方法来检索名字和中间名的输入,但是这种方法不能很好地发挥作用具有多个单词名称,因为 next()方法是基于令牌的。这意味着,如果将两个单词的名称提供给名字提示,则仅检索第一个单词,并将第二个单词自动应用于“中间名”提示。您甚至没有机会输入中间名。除非制定特殊的代码来解决这种情况,否则这是没有好处的。在这种情况下,最好不要使用 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;
}