Java 对字符串使用Sacnner nextLine时的InputMissMatchException

Java 对字符串使用Sacnner nextLine时的InputMissMatchException,java,exception,exception-handling,inputmismatchexception,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);

这是我的密码

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");
        }
    }
}
输出是

mike 0 0.0
hannigan 5 6.5
我尝试在.nextLine()中只使用一个
来获取字符串
但这会导致字符串被视为null(抛出InputMismatchException)。用试抓块

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


我的建议是始终将整行扫描为字符串,并使用解析方法将其转换为所需的数据类型。请参阅下文:

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");
    }
}
publicstaticvoidmain(字符串args[])引发IOException
{
扫描仪输入=新扫描仪(系统输入);
int n;
n=Integer.parseInt(in.nextLine());
学生[]s=新学生[n];

对于(int i=0;i我的建议是始终以字符串形式扫描整行,并使用解析方法将其转换为所需的数据类型。请参见以下内容:

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");
    }
}
publicstaticvoidmain(字符串args[])引发IOException
{
扫描仪输入=新扫描仪(系统输入);
int n;
n=Integer.parseInt(in.nextLine());
学生[]s=新学生[n];

对于(int i=0;i您的问题是理解
扫描仪时的常见错误

调用
nexttint()
nextFloat()
,或大多数其他
nextXxx()
方法将使数字后面的换行保持未处理状态

对任何
nextXxx()
方法(而不是
nextLine()
)的后续调用将自动跳过该换行,因为它是标记之间的空白

但是,
nextLine()
不会跳过前导空格,因此在任何其他
nextXxx()
方法之后调用
nextLine()
将返回空字符串(或者是最后一个标记后面的行上的任何内容)

因此,当混合使用
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);
}
Scanner-in=新的扫描仪(System.in);
int n=in.nextInt();
in.nextLine();//忽略int之后的行的其余部分
学生[]s=新学生[n];
对于(int i=0;i

更好的办法是,按照说明去做:始终使用
nextLine()
并自己解析数字。

您的问题是理解
扫描仪时常见的错误

调用
nexttint()
nextFloat()
,或大多数其他
nextXxx()
方法将使数字后面的换行保持未处理状态

对任何
nextXxx()
方法(而不是
nextLine()
)的后续调用将自动跳过该换行,因为它是标记之间的空白

但是,
nextLine()
不会跳过前导空格,因此在任何其他
nextXxx()
方法之后调用
nextLine()
将返回空字符串(或者是最后一个标记后面的行上的任何内容)

因此,当混合使用
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);
}
Scanner-in=新的扫描仪(System.in);
int n=in.nextInt();
in.nextLine();//忽略int之后的行的其余部分
学生[]s=新学生[n];
对于(int i=0;i

更好的是,按照上面说的做:始终使用
nextLine()
并自己解析数字。

这是因为
nextInt
nextFloat
不使用换行符,因此后续的
nextLine
将无法捕获您期望的数字。我肯定在某个地方有一个重复的解释……这是因为
nextInt
nextFloat
不需要请告诉我换行符,这样后续的
nextLine
就不会捕捉到您所期望的内容。我确信在某个地方有一个重复的字符可以解释这一点……这是非常常见的,因此实际上有一个规范的答案(我链接了)@4卡斯特你说得对,我忘了它是什么。当然,答案是对的。能为OP找到一个具体的解决方案是很好的。@4卡斯特这个标准答案已经在我的最爱中了,因为我经常看到这种错误。我只是忘了我有它。谢谢你提醒我。;-)这是很常见的,所以实际上有一个规范的答案(我链接了)@4卡斯特你说得对,我忘了它是什么。当然,答案是对的。能为OP找到一个具体的解决方案是很好的。@4卡斯特这个标准答案已经在我的最爱中了,因为我经常看到这种错误。我只是忘了我有它。谢谢你提醒我。;-)