Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在用户输入中区分两种数据类型?_Java - Fatal编程技术网

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()去掉这行代码
它仍然可以工作。那只是为了检查两个操作数是否都是数字。不……我的老师说它是用户友好型的……所以我不应该使用它……。谢谢发布…@汤姆谢谢-粘贴后错过了它。:-\