Java 如何在用户输入中区分两种数据类型?
我正在创建一个计算器,用户将直接输入数字和运算符 这是我的密码:Java 如何在用户输入中区分两种数据类型?,java,Java,我正在创建一个计算器,用户将直接输入数字和运算符 这是我的密码: int answer = 0; int num1, num2; char operator; System.out.print("Enter calculation: "); num1 = kb.nextInt(); operator = kb.next().charAt(0); num2 = kb.nextInt(); 当存在如下空格时,上述代码将接受用户输入: 1 + 1 Scanner scn = new Sca
int answer = 0;
int num1, num2;
char operator;
System.out.print("Enter calculation: ");
num1 = kb.nextInt();
operator = kb.next().charAt(0);
num2 = kb.nextInt();
当存在如下空格时,上述代码将接受用户输入:
1 + 1
Scanner scn = new Scanner(System.in);
Integer operand1, operand2;
char operator;
System.out.println("Enter first operand: ");
operand1 = scn.nextInt();
System.out.println("Enter operator: ");
operator = scn.next().charAt(0);
System.out.println("Enter second operand: ");
operand2 = scn.nextInt();
public class Scanners {
public static void main(String args[]) {
Lexer lexer = new Lexer("32221-8 +45 ");
for(String token : lexer)
System.out.println("token = "+token);
}
private static final class Lexer implements Iterable<String> {
private int pos=0;
private final String input;
private final int inputLength;
private String token;
public Lexer(String input) {
this.input = input;
this.inputLength = input.length();
advance();
}
private void advance() {
if(pos>=inputLength) {
token = null;
return;
}
char c = input.charAt(pos++);
if(Character.isDigit(c))
token = advanceNumber(c);
else if(Character.isJavaIdentifierStart(c))
token = advanceVariable(c);
else if(Character.isWhitespace(c)) {
advanceWhitespace();
advance();
} else
// here, assuming a one-character operator
token = Character.toString(c);
}
private String advanceNumber(char c) {
StringBuilder sb = new StringBuilder().append(c);
while(pos<inputLength) {
c = input.charAt(pos);
if(Character.isDigit(c)) {
sb.append(c);
++pos;
} else
break;
}
return sb.toString();
}
private String advanceVariable(char c) {
StringBuilder sb = new StringBuilder().append(c);
while(pos<inputLength) {
c = input.charAt(pos);
if(Character.isJavaIdentifierPart(c)) {
sb.append(c);
++pos;
} else
break;
}
return sb.toString();
}
private void advanceWhitespace() {
while(pos<inputLength && Character.isWhitespace(input.charAt(pos)))
++pos;
}
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
@Override
public boolean hasNext() {
return token != null;
}
@Override
public String next() {
String retval = token;
advance();
return retval;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
}
// output
// ------
// token = 32221
// token = -
// token = 8
// token = +
// token = 45
因此,程序将给出一个答案,即2
但是如果我输入1+1
,它将给出一个错误
Exception in thread "main" java.util.InputMismatchException
我怎样才能把整数和字符分开呢?因为我将操作符设置为character。因此,它将接受一位数到多位数的数字。像500+84
或1520/872
,30*5
,148-65
?尝试使用3扫描仪
Scanner scn = new Scanner(System.in);
int operand1, operand2;
String operator;
operand1 = Integer.parseInt(scn.next());
operator = scn.next();
operand2 = Integer.parseInt(scn.next());
OP改变了我留下的问题。
我刚发布了这个解决方案就不在了。没有时间改进它。现在我给你一个更好的和简单的解决方案:
我想你不希望用户输入像“12+45*67/20”这样的东西,对吧?假设有两个操作数
1) 将输入作为一个完整字符串接收
2) 修剪输入中的所有空格
3) 将字符串拆分为整数标记
Scanner scn = new Scanner(System.in);
String[] token = new String[12];
System.out.print("Enter equation:");
String input = scn.nextLine().trim();
String operator = "";
double answer=0, operand1=0, operand2=0;
if (input.indexOf("+") != -1){
token = input.split("\\+");
operator = "+";
}
else if (input.indexOf("-") != -1){
token = input.split("-");
operator = "-";
}
else if (input.indexOf("*") != -1){
token = input.split("\\*");
operator = "*";
}
else if (input.indexOf("/") != -1){
token = input.split("/");
operator = "/";
}
else
System.out.println("Invalid equation!");
if(token[0].matches("[0-9]+") && token[1].matches("[0-9+]"))
{
operand1 = Double.parseDouble(token[0]);
operand2 = Double.parseDouble(token[1]);
switch (operator)
{
case "+": answer = operand1 + operand2;
break;
case "-": answer = operand1 - operand2;
break;
case "*": answer = operand1 * operand2;
break;
case "/": answer = operand1 / operand2;
break;
}
}
System.out.println(answer);
只要复制并粘贴整个东西来测试它,它就会工作 您可以这样做:
1 + 1
Scanner scn = new Scanner(System.in);
Integer operand1, operand2;
char operator;
System.out.println("Enter first operand: ");
operand1 = scn.nextInt();
System.out.println("Enter operator: ");
operator = scn.next().charAt(0);
System.out.println("Enter second operand: ");
operand2 = scn.nextInt();
public class Scanners {
public static void main(String args[]) {
Lexer lexer = new Lexer("32221-8 +45 ");
for(String token : lexer)
System.out.println("token = "+token);
}
private static final class Lexer implements Iterable<String> {
private int pos=0;
private final String input;
private final int inputLength;
private String token;
public Lexer(String input) {
this.input = input;
this.inputLength = input.length();
advance();
}
private void advance() {
if(pos>=inputLength) {
token = null;
return;
}
char c = input.charAt(pos++);
if(Character.isDigit(c))
token = advanceNumber(c);
else if(Character.isJavaIdentifierStart(c))
token = advanceVariable(c);
else if(Character.isWhitespace(c)) {
advanceWhitespace();
advance();
} else
// here, assuming a one-character operator
token = Character.toString(c);
}
private String advanceNumber(char c) {
StringBuilder sb = new StringBuilder().append(c);
while(pos<inputLength) {
c = input.charAt(pos);
if(Character.isDigit(c)) {
sb.append(c);
++pos;
} else
break;
}
return sb.toString();
}
private String advanceVariable(char c) {
StringBuilder sb = new StringBuilder().append(c);
while(pos<inputLength) {
c = input.charAt(pos);
if(Character.isJavaIdentifierPart(c)) {
sb.append(c);
++pos;
} else
break;
}
return sb.toString();
}
private void advanceWhitespace() {
while(pos<inputLength && Character.isWhitespace(input.charAt(pos)))
++pos;
}
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
@Override
public boolean hasNext() {
return token != null;
}
@Override
public String next() {
String retval = token;
advance();
return retval;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
}
// output
// ------
// token = 32221
// token = -
// token = 8
// token = +
// token = 45
它不需要负操作数。如果数字太大,它会抛出异常。它没有解释什么是“表达式中的错误”。因此,还有很大的改进空间
Scanner scn = new Scanner( System.in );
Pattern pat = Pattern.compile( "\\s*(\\d+)\\s*([-+*/])\\s*(\\d+)\\s*" );
while( scn.hasNextLine() ){
String line = scn.nextLine();
Matcher mat = pat.matcher( line );
if( mat.matches() ){
int op1 = Integer.parseInt( mat.group(1) );
char od = mat.group(2).charAt(0);
int op2 = Integer.parseInt( mat.group(3) );
System.out.println( op1 + " " + od + " " + op2 );
} else {
System.out.println( "error in expression" );
}
}
这是一个更简单的版本。类似的警告也适用于此。此外,它对无效数字抛出异常,并接受几乎任何运算符
Scanner scn = new Scanner( System.in );
scn.useDelimiter( "\\b|\\s+" );
while( scn.hasNextLine() ){
int op1 = scn.nextInt();
char od = scn.next().charAt(0);
int op2 = scn.nextInt();
System.out.println( op1 + " " + od + " " + op2 );
scn.nextLine();
}
我对
java.util.Scanner
类没有太多经验。但是,我怀疑它在定义良好的标记分隔符上标记,例如空格、制表符、逗号、管道字符等。因此,在标记输入类型时,这可能是一个糟糕的选择
为了成功地标记您的输入类型,我建议实现适当的词法分析器。这可能有点过分了(比如用坦克猎杀兔子),但要想在一定程度上保证成功,就需要编写一个词法分析器。网络上充斥着编写词法分析器的例子。对于您的输入,它可能如下所示:
1 + 1
Scanner scn = new Scanner(System.in);
Integer operand1, operand2;
char operator;
System.out.println("Enter first operand: ");
operand1 = scn.nextInt();
System.out.println("Enter operator: ");
operator = scn.next().charAt(0);
System.out.println("Enter second operand: ");
operand2 = scn.nextInt();
public class Scanners {
public static void main(String args[]) {
Lexer lexer = new Lexer("32221-8 +45 ");
for(String token : lexer)
System.out.println("token = "+token);
}
private static final class Lexer implements Iterable<String> {
private int pos=0;
private final String input;
private final int inputLength;
private String token;
public Lexer(String input) {
this.input = input;
this.inputLength = input.length();
advance();
}
private void advance() {
if(pos>=inputLength) {
token = null;
return;
}
char c = input.charAt(pos++);
if(Character.isDigit(c))
token = advanceNumber(c);
else if(Character.isJavaIdentifierStart(c))
token = advanceVariable(c);
else if(Character.isWhitespace(c)) {
advanceWhitespace();
advance();
} else
// here, assuming a one-character operator
token = Character.toString(c);
}
private String advanceNumber(char c) {
StringBuilder sb = new StringBuilder().append(c);
while(pos<inputLength) {
c = input.charAt(pos);
if(Character.isDigit(c)) {
sb.append(c);
++pos;
} else
break;
}
return sb.toString();
}
private String advanceVariable(char c) {
StringBuilder sb = new StringBuilder().append(c);
while(pos<inputLength) {
c = input.charAt(pos);
if(Character.isJavaIdentifierPart(c)) {
sb.append(c);
++pos;
} else
break;
}
return sb.toString();
}
private void advanceWhitespace() {
while(pos<inputLength && Character.isWhitespace(input.charAt(pos)))
++pos;
}
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
@Override
public boolean hasNext() {
return token != null;
}
@Override
public String next() {
String retval = token;
advance();
return retval;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
}
// output
// ------
// token = 32221
// token = -
// token = 8
// token = +
// token = 45
公共类扫描仪{
公共静态void main(字符串参数[]){
Lexer Lexer=新Lexer(“32221-8+45”);
for(字符串标记:lexer)
System.out.println(“token=“+token”);
}
私有静态最终类Lexer实现Iterable{
私人int pos=0;
私有最终字符串输入;
私有最终整数输入长度;
私有字符串令牌;
公共Lexer(字符串输入){
这个输入=输入;
this.inputLength=input.length();
前进();
}
私人预支{
如果(位置>=输入长度){
令牌=null;
返回;
}
charc=input.charAt(pos++);
if(字符isDigit(c))
令牌=高级编号(c);
else if(Character.isJavaIdentifierStart(c))
令牌=高级变量(c);
else if(Character.isWhitespace(c)){
高级空格();
前进();
}否则
//这里,假设一个单字符操作符
token=字符.toString(c);
}
专用字符串高级编号(字符c){
StringBuilder sb=新的StringBuilder()。追加(c);
while(pos)您遇到与OP相同的问题,只是另一个例外。@RavenMaddison这不是真的。@RavenMaddison作为扫描仪的下一个()返回一个java.lang.String,编译器将接受它。@RavenMaddison我添加了一些代码。它将100%工作。我使用简单的代码使它工作,所以你的学校应该接受它。即使你用.matches()去掉这行代码
它仍然可以工作。那只是为了检查两个操作数是否都是数字。不……我的老师说它是用户友好型的……所以我不应该使用它……。谢谢发布…@汤姆谢谢-粘贴后错过了它。:-\