使用Sacnner nextLine for String时的InputMismatchException

时间:2016-07-12 04:13:56

标签: java exception exception-handling inputmismatchexception

这是我的代码

import java.io.*;
import java.util.*;
class student
{
    String name;
    int age;
    float cgpa;
}
public class getdata
{

    public static void main(String args[]) throws IOException
    {
        Scanner in=new Scanner(System.in);
        int n;
        n=in.nextInt();
        student[] s=new student[n];
        for(int i=0;i<n;i++)
        {
            try
            {
                s[i]=new student();
                s[i].name=in.nextLine();
                in.nextLine();
                s[i].age=in.nextInt();
                s[i].cgpa=in.nextFloat();
            }
            catch(InputMismatchException e)
            {
                System.out.println(e.getMessage());
            }
        }
        System.out.println();
        System.out.println("Name\tAge\tCGPA\n");
        for(int i=0;i<n;i++)
        {
            System.out.println(s[i].name+"\t"+s[i].age+"\t"+s[i].cgpa+"\n");
        }
    }
}

编译程序没有问题。但是当执行并且我尝试输入字符串空间时,它将字符串作为两个单独的字符串并将一个的所有其他值分配为null。例如,如果我输入

mike hannigan
5
6.5

输出

mike 0 0.0
hannigan 5 6.5

我尝试只使用一个in.nextLine();获取字符串,但这会导致字符串被视为null(抛出InputMismatchException)。用try和catch块

with try block

并且没有try块,这是我得到的输出

enter image description here

2 个答案:

答案 0 :(得分:2)

我的建议是始终将整行​​扫描为String并使用解析方法将其转换为所需的数据类型。请参阅以下内容:

public static void main(String args[]) throws IOException
{
    Scanner in=new Scanner(System.in);
    int n;
    n=Integer.parseInt(in.nextLine());
    student[] s=new student[n];
    for(int i=0;i<n;i++)
    {
            s[i]=new student();
            s[i].name=in.nextLine();
            s[i].age=Integer.parseInt(in.nextLine());
            s[i].cgpa=Float.parseFloat(in.nextLine());

    }
    System.out.println();
    System.out.println("Name\tAge\tCGPA\n");
    for(int i=0;i<n;i++)
    {
        System.out.println(s[i].name+"\t"+s[i].age+"\t"+s[i].cgpa+"\n");
    }
}

答案 1 :(得分:0)

您的问题是理解Scanner时常见的错误。

调用nextInt()nextFloat()或大多数其他nextXxx()方法会在未处理的数字后面留下换行符。

随后调用任何nextXxx()方法,除 nextLine()以外的,将自动跳过该换行符,因为在令牌之间有空格。

但是,nextLine() 会跳过前导空格,因此在任何其他nextLine()方法之后调用nextXxx()将返回一个空字符串(或者更确切地说是在最后一个令牌后面的其余部分)。

因此,当混合 nextXxx()调用nextLine()次调用时,您必须首先调用nextLine()来刷新(丢弃)上一行的结尾。

这意味着您的代码应为:

Scanner in = new Scanner(System.in);
int n = in.nextInt();
in.nextLine(); // Ignore rest of line after int
student[] s = new student[n];
for (int i = 0; i < n; i++) {
    s[i] = new student();
    s[i].name = in.nextLine();
    s[i].age = in.nextInt();
    s[i].cgpa = in.nextFloat();
    in.nextLine(); // Ignore rest of line after float
}
System.out.println();
System.out.println("Name\tAge\tCGPA");
for (int i = 0; i < n; i++) {
    System.out.println(s[i].name + "\t" + s[i].age + "\t" + s[i].cgpa);
}

更好的是,执行answer by @JaganathanNanthakumar所说的内容:始终使用nextLine()并自行解析数字。