简体   繁体   English

Java扫描器从我的文本文件读取null吗?

[英]Java scanner reading null from my text file?

I'm writing some code to read an input file of book titles, and putting the read lines into an array and trying to print out the array. 我正在编写一些代码来读取书名的输入文件,并将读取的行放入数组中并尝试打印出该数组。 But when I try to print out the array, it just returns 'null' for each read line. 但是,当我尝试打印出数组时,它只会为每个读取行返回“ null”。 I'm not sure what I'm doing wrong or what my code is doing. 我不确定自己在做什么错或我的代码在做什么。 Any suggestions? 有什么建议么? Thanks! 谢谢!

Code: 码:

    import java.io.*;
import java.util.*;
public class LibraryInputandOutputs {
    public static void main(String args[]) throws IOException{
        int lineCount = 0;
        File inputFile = new File("bookTitles.inp.txt");
        Scanner reader = new Scanner(inputFile);
        while(reader.hasNextLine()) {
            reader.nextLine();
            lineCount++;
        }

        String[] bookArray = new String[lineCount];
        while (reader.hasNextLine()) {
            for (int i = 0; i < lineCount; i++) {
                bookArray[i] = reader.next();
             }
        }
        for (int k = 0; k < lineCount; k++) {
            System.out.println(bookArray[k]);
        }
        reader.close();
        inputFile.close();

    }
}

My text file I'm reading from is 20 book titles, all on different lines. 我正在阅读的文本文件有20种书名,它们都在不同的行上。 My output on the terminal is 20 lines of null. 我在终端上的输出是20行的null。

Lets break this down: 让我们分解一下:

  1. This reads every line of the input file, counts each one, and then discards them: 这将读取输入文件的每一行,对每一行进行计数,然后将其丢弃:

     while(reader.hasNextLine()) { reader.nextLine(); lineCount++; } 

    You are now at the end of file. 您现在位于文件末尾。

  2. Allocate a string array that is large enough. 分配足够大的字符串数组。

     String[] bookArray = new String[lineCount]; 
  3. Attempt to read more lines. 尝试阅读更多行。 The loop will terminate immediately because reader.hasNextLine() will return false . 该循环将立即终止,因为reader.hasNextLine()将返回false You are already at the end of file. 已经在文件末尾了。

    So you the statement assigning to bookArray[i] won't be executed. 因此,将不会执行分配给bookArray[i]的语句。

     while (reader.hasNextLine()) { for (int i = 0; i < lineCount; i++) { bookArray[i] = reader.next(); } } 
  4. Since bookArray[i] = ... was never executed above, all of the array elements will still be null . 由于bookArray[i] = ...从未在上面执行过,因此所有数组元素仍将为null

     for (int k = 0; k < lineCount; k++) { System.out.println(bookArray[k]); } 

One solution is to open and read the file twice. 一种解决方案是打开并读取文件两次。

Another solution is to "reset" the file back to the beginning. 另一个解决方案是将文件“重置”回开始。 (A bit complicated.) (有点复杂。)

Another solution would be to use a List rather than an array so that you don't need to read the file twice. 另一种解决方案是使用List而不是数组,这样您就不需要两次读取文件。

Another solution is to search the javadocs for a method that will read all lines of a file / stream as an array of strings. 另一个解决方案是在javadocs中搜索一种方法,该方法将以字符串数组的形式读取文件/流的所有行。

(Some of these may be precluded by the requirements of your exercise. You work it out ... ) (其中一些要求可能会因您的锻炼要求而被排除需要进行锻炼...)


The nested loop in step 3 is also wrong. 步骤3中的嵌套循环也是错误的。 You don't need a for loop inside a while loop. 在while循环内不需要for循环。 You need a single loop that "iterates" the over the lines and also increments the array index ( i ). 您需要一个循环来“遍历”行并增加数组索引( i )。 They don't both need to be done by the loop statement itself. 它们都不需要由loop语句本身完成。 You could do one or the other (or both) in the loop body. 您可以在循环主体中执行一个或另一个(或同时执行两个)。

Stephen C has already pointed out the main problems with your logic. Stephen C已经指出了您的逻辑存在的主要问题。 You're trying to loop twice through the file but you've already reached the end of the file the first time. 您试图在文件中循环两次,但是第一次已经到达文件末尾。 Don't loop twice. 不要循环两次。 "Merge" both the while loops into one, remove that for loop inside the while loop and collect all the book titles. 将两个while循环“合并”为一个,在while循环中删除for循环,并收集所有书名。 You can then use the size of the list to print them later on. 然后,您可以使用列表的大小在以后打印它们。 My Java might be rusty but here it goes - 我的Java可能会生锈,但是在这里-

import java.io.*;
import java.util.*;
public class LibraryInputandOutputs {
    public static void main(String args[]) throws IOException {

        // int lineCount = 0; - You don't need this.

        File inputFile = new File("bookTitles.inp.txt");
        Scanner reader = new Scanner(inputFile);

        // Use an array list to collect book titles.
        List<String> bookArray = new ArrayList<>(); 

        // Loop through the file and add titles to the array list.
        while(reader.hasNextLine()) {
            bookArray.add(reader.nextLine());
            // lineCount++; - not needed
        }

        // Not needed -
        // while (reader.hasNextLine()) {
        //     for (int i = 0; i < lineCount; i++) {
        //         bookArray[i] = reader.next();
        //      }
        // }

        // Use the size method of the array list class to get the length of the list 
        // and use it for looping.
        for (int k = 0; k < bookArray.size(); k++) {  
            System.out.println(bookArray[k]);
        }

        reader.close();
        inputFile.close();

    }
}

I agree with Stephen C. In particular, using a List is usually better than an array because it's more flexible. 我同意StephenC。特别是,使用List通常比数组更好,因为它更灵活。 If you need an array, you can always use toArray() after the List is filled. 如果需要数组,则在列表填充后始终可以使用toArray()。

Are your book titles on separate lines? 您的书名是否分开? If so you might not need a Scanner class, and could use something like a BufferedReader or LineNumberReader. 如果是这样,您可能不需要Scanner类,可以使用BufferedReader或LineNumberReader之类的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM