while 循环语句中的扫描器函数导致运行时错误
Scanner function in while loop's statement causes runtime error
通过使用调试器,我设法找到了问题,但我不知道如何解决它。
导入java.util.*;
public class CreateString {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StringBuilder solution = new StringBuilder();
while (scanner.hasNext()){
Scanner inner_scanner = new Scanner(scanner.nextLine());
String str = inner_scanner.next();
while(inner_scanner.hasNextInt()) solution.append(str.charAt(inner_scanner.nextInt()));
inner_scanner.close();
}
System.out.format("%d\n %s",solution.length(),solution);
scanner.close();
}
}
这就是我所说的 while 循环。这段代码的基本前提是我得到一个输入,首先是一个字符串,然后是几个数字。像这样:
some_string 0 5 1 4
在输出中,我写出了这些数字索引到的索引中的字符。所以我得到:
s_oe
问题是当它完成一个循环时,它会卡住并等待下一个输入。
假设您使用的所有循环和扫描仪都不是强制性的,如果我是您,我会按照以下方式进行操作:
解决方案 1:(未测试)
- Scanner.nextXXX() 读取整行。所以
some_string 0 5 1 4
只会读到一个.nextLine()
。为了那个原因:
- 我阅读了
String str
,
- 然后将其拆分为
params
。如果字符串 word
位于单元格 0,则后续单元格会将索引保留在参数中。
- 我解析了int中的每个索引,然后在字符串中选择了相应的字符
word
。
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StringBuilder solution = new StringBuilder();
String str = scanner.nextLine();
String[] params = str.split(" ");
String word = params[0];
String output = "";
for(int i=1; i < params.length; i++) {
int index = Integer.parseInt(params[i]);
output += word.substring(index, index+1);
}
}
解决方案 2:(未测试)
- 在这里我等待参数作为应用程序的参数。所以他们将传递 main 方法的参数(String args)。看看这个 page
public static void main(String[] args) {
String word = args[0];
String output = "";
for(int i=1; i < params.length; i++) {
int index = Integer.parseInt(args[i]);
output += word.substring(index, index+1);
}
System.out.println(output);
}
测试解决方案2:
javac Application.java
java Application some_string 0 5 1 4
解决方案 3(已测试)
现在我明白你的问题了。
这与您解释的完全一样。但是要停止你必须输入“exit”。
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String inputStr = scanner.nextLine();
String[] params = inputStr.split(" ");
String word = params[0];
boolean stop = word.equals("exit"); // check if we need to stop
while( ! stop ) {
String output = "";
for (int i = 1; i < params.length; i++) {
int index = Integer.parseInt(params[i]);
if(word.length() >= (index+1))
output += word.charAt(index);
}
System.out.println(output); // print result
// read params for next step
inputStr = scanner.nextLine();
params = inputStr.split(" ");
word = params[0];
stop = word.equals("exit"); // check if we need to stop
}
}
System.out.println("Exit !");
}
scanner.hasNext() 将继续等待输入,直到到达 EOF 字符。我认为你唯一的选择是要么硬编码一个特殊字符来打破循环,要么按照这些行做一些事情:
public static void main(String[] args) {
StringBuilder solution = new StringBuilder();
try (Scanner scanner = new Scanner(System.in)) {
String string = scanner.next();
String[] indexes = scanner.nextLine().trim().split(" ");
for (String index : indexes) {
int parsedIndex = Integer.parseInt(index);
if (parsedIndex >= 0 && parsedIndex < string.length()) {
solution.append(string.charAt(parsedIndex));
}
}
System.out.printf("%d\n%s", solution.length(), solution);
}
}
只用一个Scanner
:
public static void main(String[] args) {
var scanner = new Scanner(System.in);
var solution = new StringBuilder();
while (scanner.hasNextLine()){
var str = scanner.next();
while (scanner.hasNextInt()) {
solution.append(str.charAt(scanner.nextInt()));
}
scanner.nextLine();
}
System.out.format("%d\n %s\n",solution.length(),solution);
}
尽量不改变主要结构(太多)
但使用 hasNextInt()
将避免内循环在下一个标记出现之前完成 - 因此如果您需要为每个输入行一个输出,则需要另一种方法。
public static void main(String[] args) {
var scanner = new Scanner(System.in);
while (scanner.hasNextLine()){
var solution = new StringBuilder();
var str = scanner.next();
var inner = new Scanner(scanner.nextLine());
while (inner.hasNextInt()) {
solution.append(str.charAt(inner.nextInt()));
}
inner.close();
System.out.format("%d\n %s\n",solution.length(),solution);
}
}
或者,更好的是,使用 try-with resource
,如 Alex :
var scanner = new Scanner(System.in);
while (scanner.hasNextLine()){
var solution = new StringBuilder();
var str = scanner.next();
try (var inner = new Scanner(scanner.nextLine())) {
while (inner.hasNextInt()) {
solution.append(str.charAt(inner.nextInt()));
}
}
System.out.format("%d\n %s\n",solution.length(),solution);
}
在 Windows 上,您需要在自己的行上键入 Ctrl
-Z
,然后键入 Return
以结束标准输入(如果我是没有错)
通过使用调试器,我设法找到了问题,但我不知道如何解决它。
导入java.util.*;
public class CreateString {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StringBuilder solution = new StringBuilder();
while (scanner.hasNext()){
Scanner inner_scanner = new Scanner(scanner.nextLine());
String str = inner_scanner.next();
while(inner_scanner.hasNextInt()) solution.append(str.charAt(inner_scanner.nextInt()));
inner_scanner.close();
}
System.out.format("%d\n %s",solution.length(),solution);
scanner.close();
}
}
这就是我所说的 while 循环。这段代码的基本前提是我得到一个输入,首先是一个字符串,然后是几个数字。像这样:
some_string 0 5 1 4
在输出中,我写出了这些数字索引到的索引中的字符。所以我得到:
s_oe
问题是当它完成一个循环时,它会卡住并等待下一个输入。
假设您使用的所有循环和扫描仪都不是强制性的,如果我是您,我会按照以下方式进行操作:
解决方案 1:(未测试)
- Scanner.nextXXX() 读取整行。所以
some_string 0 5 1 4
只会读到一个.nextLine()
。为了那个原因:- 我阅读了
String str
, - 然后将其拆分为
params
。如果字符串word
位于单元格 0,则后续单元格会将索引保留在参数中。 - 我解析了int中的每个索引,然后在字符串中选择了相应的字符
word
。
- 我阅读了
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StringBuilder solution = new StringBuilder();
String str = scanner.nextLine();
String[] params = str.split(" ");
String word = params[0];
String output = "";
for(int i=1; i < params.length; i++) {
int index = Integer.parseInt(params[i]);
output += word.substring(index, index+1);
}
}
解决方案 2:(未测试)
- 在这里我等待参数作为应用程序的参数。所以他们将传递 main 方法的参数(String args)。看看这个 page
public static void main(String[] args) {
String word = args[0];
String output = "";
for(int i=1; i < params.length; i++) {
int index = Integer.parseInt(args[i]);
output += word.substring(index, index+1);
}
System.out.println(output);
}
测试解决方案2:
javac Application.java
java Application some_string 0 5 1 4
解决方案 3(已测试)
现在我明白你的问题了。
这与您解释的完全一样。但是要停止你必须输入“exit”。
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
String inputStr = scanner.nextLine();
String[] params = inputStr.split(" ");
String word = params[0];
boolean stop = word.equals("exit"); // check if we need to stop
while( ! stop ) {
String output = "";
for (int i = 1; i < params.length; i++) {
int index = Integer.parseInt(params[i]);
if(word.length() >= (index+1))
output += word.charAt(index);
}
System.out.println(output); // print result
// read params for next step
inputStr = scanner.nextLine();
params = inputStr.split(" ");
word = params[0];
stop = word.equals("exit"); // check if we need to stop
}
}
System.out.println("Exit !");
}
scanner.hasNext() 将继续等待输入,直到到达 EOF 字符。我认为你唯一的选择是要么硬编码一个特殊字符来打破循环,要么按照这些行做一些事情:
public static void main(String[] args) {
StringBuilder solution = new StringBuilder();
try (Scanner scanner = new Scanner(System.in)) {
String string = scanner.next();
String[] indexes = scanner.nextLine().trim().split(" ");
for (String index : indexes) {
int parsedIndex = Integer.parseInt(index);
if (parsedIndex >= 0 && parsedIndex < string.length()) {
solution.append(string.charAt(parsedIndex));
}
}
System.out.printf("%d\n%s", solution.length(), solution);
}
}
只用一个Scanner
:
public static void main(String[] args) {
var scanner = new Scanner(System.in);
var solution = new StringBuilder();
while (scanner.hasNextLine()){
var str = scanner.next();
while (scanner.hasNextInt()) {
solution.append(str.charAt(scanner.nextInt()));
}
scanner.nextLine();
}
System.out.format("%d\n %s\n",solution.length(),solution);
}
尽量不改变主要结构(太多)
但使用 hasNextInt()
将避免内循环在下一个标记出现之前完成 - 因此如果您需要为每个输入行一个输出,则需要另一种方法。
public static void main(String[] args) {
var scanner = new Scanner(System.in);
while (scanner.hasNextLine()){
var solution = new StringBuilder();
var str = scanner.next();
var inner = new Scanner(scanner.nextLine());
while (inner.hasNextInt()) {
solution.append(str.charAt(inner.nextInt()));
}
inner.close();
System.out.format("%d\n %s\n",solution.length(),solution);
}
}
或者,更好的是,使用 try-with resource
,如 Alex
var scanner = new Scanner(System.in);
while (scanner.hasNextLine()){
var solution = new StringBuilder();
var str = scanner.next();
try (var inner = new Scanner(scanner.nextLine())) {
while (inner.hasNextInt()) {
solution.append(str.charAt(inner.nextInt()));
}
}
System.out.format("%d\n %s\n",solution.length(),solution);
}
在 Windows 上,您需要在自己的行上键入 Ctrl
-Z
,然后键入 Return
以结束标准输入(如果我是没有错)