如何使用java.util.Scanner从System.in正确读取用户输入并对其执行操作?
这是一个标准问题/答案,可以用作 重复目标。这些要求基于最常见的 每天发布的问题,可根据需要添加到。他们都 需要相同的基本代码结构才能访问每个场景 它们通常相互依赖如何使用java.util.Scanner从System.in正确读取用户输入并对其执行操作?,java,java.util.scanner,system.in,Java,Java.util.scanner,System.in,这是一个标准问题/答案,可以用作 重复目标。这些要求基于最常见的 每天发布的问题,可根据需要添加到。他们都 需要相同的基本代码结构才能访问每个场景 它们通常相互依赖 Scanner看起来是一个“简单”的类,这就是第一个错误的地方。它并不简单,它有各种不明显的副作用和异常行为,以非常微妙的方式打破了最小惊讶原则 这对这门课来说似乎有些过分,但是剥洋葱的错误和问题都很简单,但是综合起来,它们非常复杂,因为它们之间的相互作用和副作用。这就是为什么每天都有那么多关于堆栈溢出的问题 常见扫描仪问题: 大
Scanner看起来是一个“简单”的类,这就是第一个错误的地方。它并不简单,它有各种不明显的副作用和异常行为,以非常微妙的方式打破了最小惊讶原则 这对这门课来说似乎有些过分,但是剥洋葱的错误和问题都很简单,但是综合起来,它们非常复杂,因为它们之间的相互作用和副作用。这就是为什么每天都有那么多关于堆栈溢出的问题 常见扫描仪问题: 大多数
Scanner
问题都包括在以上一个方面的失败尝试
2014/10/18
)http://google.com
)Scanner
是一个特例,这是一门极其挑剔的课程,老师不应该给新生使用的指导。在大多数情况下,教师甚至不知道如何正确使用它。它几乎从未在专业生产代码中使用过,因此它对学生的价值是非常值得怀疑的
使用Scanner
意味着这个问题和答案提到的所有其他事情。它绝不仅仅是关于扫描仪
的问题,而是关于如何解决扫描仪
的这些常见问题,这些问题在几乎所有的扫描仪
出错的问题中都是共病问题。它绝不仅仅是关于,这只是类实现挑剔的一个症状,代码中总是有其他问题,在询问Scanner
的问题中
答案显示了99%使用Scanner
并询问有关StackOverflow的情况的完整、惯用的实现
尤其是在初学者代码中。如果你认为这个答案太复杂,那么在解释其行为的复杂性、怪癖、不明显的副作用和特点之前,先向指导老师投诉,让新生使用扫描仪
Scanner
是一个很好的教学时刻,它告诉我们在命名方法和方法参数时,一致的行为和语义有多重要,以及为什么一致的行为和语义很重要
学生须知:
您可能永远不会真正看到在中使用的扫描仪
专业/商业业务线应用程序,因为它
做其他事情做得更好。现实世界的软件必须
比扫描仪
更具弹性和可维护性
代码。真实世界的软件使用标准化的文件格式解析器和
文件格式,而不是您正在使用的特殊输入格式
在独立作业中给出
惯用的例子:
<> >如何正确使用< C++ > java .UTI.Spults类来交互式地读取<代码>系统中的用户输入。在正确(有时称为代码> STDIN < /代码>,特别是在C、C++和其他语言以及UNIX和Linux中)。它惯用地演示了需要完成的最常见的事情
package com.stackoverflow.scanner;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
import static java.lang.String.format;
public class ScannerExample
{
private static final Set<String> EXIT_COMMANDS;
private static final Set<String> HELP_COMMANDS;
private static final Pattern DATE_PATTERN;
private static final String HELP_MESSAGE;
static
{
final SortedSet<String> ecmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
ecmds.addAll(Arrays.asList("exit", "done", "quit", "end", "fino"));
EXIT_COMMANDS = Collections.unmodifiableSortedSet(ecmds);
final SortedSet<String> hcmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
hcmds.addAll(Arrays.asList("help", "helpi", "?"));
HELP_COMMANDS = Collections.unmodifiableSet(hcmds);
DATE_PATTERN = Pattern.compile("\\d{4}([-\\/])\\d{2}\\1\\d{2}"); // http://regex101.com/r/xB8dR3/1
HELP_MESSAGE = format("Please enter some data or enter one of the following commands to exit %s", EXIT_COMMANDS);
}
/**
* Using exceptions to control execution flow is always bad.
* That is why this is encapsulated in a method, this is done this
* way specifically so as not to introduce any external libraries
* so that this is a completely self contained example.
* @param s possible url
* @return true if s represents a valid url, false otherwise
*/
private static boolean isValidURL(@Nonnull final String s)
{
try { new URL(s); return true; }
catch (final MalformedURLException e) { return false; }
}
private static void output(@Nonnull final String format, @Nonnull final Object... args)
{
System.out.println(format(format, args));
}
public static void main(final String[] args)
{
final Scanner sis = new Scanner(System.in);
output(HELP_MESSAGE);
while (sis.hasNext())
{
if (sis.hasNextInt())
{
final int next = sis.nextInt();
output("You entered an Integer = %d", next);
}
else if (sis.hasNextLong())
{
final long next = sis.nextLong();
output("You entered a Long = %d", next);
}
else if (sis.hasNextDouble())
{
final double next = sis.nextDouble();
output("You entered a Double = %f", next);
}
else if (sis.hasNext("\\d+"))
{
final BigInteger next = sis.nextBigInteger();
output("You entered a BigInteger = %s", next);
}
else if (sis.hasNextBoolean())
{
final boolean next = sis.nextBoolean();
output("You entered a Boolean representation = %s", next);
}
else if (sis.hasNext(DATE_PATTERN))
{
final String next = sis.next(DATE_PATTERN);
output("You entered a Date representation = %s", next);
}
else // unclassified
{
final String next = sis.next();
if (isValidURL(next))
{
output("You entered a valid URL = %s", next);
}
else
{
if (EXIT_COMMANDS.contains(next))
{
output("Exit command %s issued, exiting!", next);
break;
}
else if (HELP_COMMANDS.contains(next)) { output(HELP_MESSAGE); }
else { output("You entered an unclassified String = %s", next); }
}
}
}
/*
This will close the underlying InputStream, in this case System.in, and free those resources.
WARNING: You will not be able to read from System.in anymore after you call .close().
If you wanted to use System.in for something else, then don't close the Scanner.
*/
sis.close();
System.exit(0);
}
}
package com.stackoverflow.scanner;
导入javax.annotation.Nonnull;
导入java.math.biginger;
导入java.net.MalformedURLException;
导入java.net.URL;
导入java.util.*;
导入java.util.regex.Pattern;
导入静态java.lang.String.format;
公共类扫描程序示例
{
专用静态最终设置退出命令;
专用静态最终设置帮助_命令;
私有静态最终模式日期\模式;
私有静态最终字符串帮助_消息;
静止的
{
最终分类集ecmds=新树集(字符串不区分大小写顺序);
addAll(Arrays.asList(“exit”、“done”、“quit”、“end”、“fino”));
EXIT_COMMANDS=Collections.unmodifiableSortedSet(ecmds);
最终分拣集hcmds=新的树集(字符串不区分大小写\u顺序);
addAll(Arrays.asList(“help”、“helpi”和“?”));
HELP\u COMMANDS=Collections.unmodifiableSet(hcmds);
DATE\u PATTERN=PATTERN.compile(“\\d{4}([-\\/])\\d{2}\\1\\d{2}”);//http://regex101.com/r/xB8dR3/1
HELP_MESSAGE=format(“请输入一些数据或输入以下命令之一以退出%s”,退出_命令);
}
/**
*使用异常来控制执行流总是不好的。
*这就是为什么它被封装在一个方法中,这是这样做的
*以避免引入任何外部库
*所以这是一个完全独立的例子。
*@param的可能url
*@如果s表示有效url,则返回true,否则返回false
*/
私有静态布尔值isValidURL(@Nonnull final String s)
{
尝试{新URL;返回true;}
catch(final malformedurexception e){return false;}
}
私有静态无效输出(@Nonnull最终字符串格式,@Nonnull最终对象…args)
{
System.out.println(格式(format,args));
}