Java 如果输入文件末尾没有空行,则会报错

Java gives an error if there's no blank line at end of Input file

我在尝试将文件读入 Java 时遇到了一个奇怪的问题。只要输入文件末尾有一个空行,我就可以读取文件中的所有内容。如果没有空行,它会崩溃。这是为什么?

一段时间后我发现问题是空行。只要输入文件最后有一个空行就可以了

运行 没有问题的输入文件:

会报错的输入文件:

注意行号!

public static void main(String[] args) {

        String fileInputName;
        String fileOutputName;

        String firstName;
            String lastName;
            String houseNumber;
            String street;
            String city;
            String state;
            String zip;

            String productDescription;
            double productPrice = 0;
            double productCost = 0;
            int productQuantity = 0;

            int totalQuantity = 0;
            double totalCost = 0;


        Scanner input = null;
        input = new Scanner(System.in);

        System.out.printf("What is the file name?\n");


        fileInputName = input.nextLine();


        System.out.println("File name is: " + fileInputName);

        FileReader filereader;
        Scanner readInput = null;


        try {
            readInput = new Scanner(new FileReader(fileInputName));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //Header
        firstName = readInput.nextLine();
        lastName = readInput.nextLine();
        houseNumber = readInput.nextLine();
        street = readInput.nextLine();
        city = readInput.nextLine();
        state = readInput.nextLine();
        zip = readInput.nextLine();

        System.out.printf("Purchase Report\n---------------\n%s %s\n%s %s\n%s, %s %s\n\n"
                + "Description\t\t\tPrice\tQuantity\tCost\n"
                + "-----------\t\t\t-----\t--------\t----\n", 
                firstName, lastName, houseNumber, street, city, state, zip);

        while (readInput.hasNextLine())
        {
            productDescription = readInput.nextLine();
            productPrice = readInput.nextDouble();
            readInput.nextLine();
            productQuantity = readInput.nextInt();
            readInput.nextLine();

            productCost = productPrice * productQuantity;

            totalCost += productCost;
            totalQuantity += productQuantity;
            System.out.printf("%-30s%7.2f\t%8d     %7.2f\n", 
                    productDescription, productPrice, productQuantity, productCost);
        }

        //Footer
        System.out.printf("-----------\t\t\t-----\t--------\t----\n"
                + "Total\t\t\t\t\t%8d     %7.2f\n", totalQuantity, totalCost);

        readInput.close();      

    }
}

不加行应该也能看吧?谁能向我解释发生了什么以及如何解决它?谢谢!

正如评论中有人提到的那样,您对 readInput.nextLine(); 的最后一次调用失败了,因为没有什么可读的了。在较早的迭代中,它会清除该行的其余部分以及可能的任何换行符,但文件末尾不存在这些字符。

另一种解决方案是简单地为任何行调用 readInput.nextLine() 而不是 nextInt 并使用 Integer.parseInt 单独解析它,例如。

当你在调用nextXxx()之后调用nextLine()时,它会读取该行的rest,这通常只是行尾字符。

当最后一行的末尾没有行尾字符时,这意味着您在调用 nextInt() 后已经在文件末尾,即为什么无条件 nextLine() 调用失败。

两种修复方式:

  1. 不要无条件调用nextLine():

    productDescription = readInput.nextLine();
    productPrice = readInput.nextDouble();
    readInput.nextLine();
    productQuantity = readInput.nextInt();
    if (readInput.hasNextLine())
        readInput.nextLine();
    
  2. 不要使用nextXxx():

    productDescription = readInput.nextLine();
    productPrice = Double.parseDouble(readInput.nextLine().trim());
    productQuantity = Integer.parseInt(readInput.nextLine().trim());
    

    trim() 应该不是必需的,但使代码与现有代码保持一致。

推荐选项 2,因为如果数字后面有额外的文本,它会正确地失败,而选项 1 会默默地丢弃这些额外的文本。

此外,代码更整洁。