简体   繁体   English

读取文本文件中的整数并使用扫描仪和异常存储到数组

[英]Read text file for integers and storing to array using scanner and exceptions

I'm trying to loop through a text file for integers and store integers found into an array. 我正在尝试遍历文本文件中的整数,并将找到的整数存储到数组中。

Using a try-catch to determine which words are integers and which are not using InputMismatchException, removing the non-int strings from the input stream. 使用try-catch来确定哪些单词是整数,哪些单词未使用InputMismatchException,从输入流中删除非整数字符串。 As well as a NoSuchElementException for blank lines in the file. 以及文件中空白行的NoSuchElementException。 My main issue is storing the integers and printing those integers in the array, in my second method :o . 我的主要问题是在第二种方法:o中存储整数并将这些整数打印在数组中。 It also appears my loop is also recording non-ints as null as well. 看来我的循环也将非整数也记录为null。 They aren't suppose be stored into the array. 它们不应该存储在数组中。

public static void main(String[] commandlineArgument) {
      Integer[] array = ReadFile6.readFileReturnIntegers(commandlineArgument[0]);
      ReadFile6.printArrayAndIntegerCount(array, commandlineArgument[0]);
   }

   public static Integer[] readFileReturnIntegers(String filename) {
      Integer[] array = new Integer[1000];
      // connect to the file
      File file = new File(filename);
      Scanner inputFile = null;
      try {
         inputFile = new Scanner(file);
      }
      // If file not found-error message
      catch (FileNotFoundException Exception) {
         System.out.println("File not found!");
      }
      // if connected, read file
      if (inputFile != null) {
      // loop through file for integers and store in array
         while (inputFile.hasNextLine()) {
            for(int i = 0; i<array.length; i++)
            {
               try{
                  array[i] = inputFile.nextInt();
               }
               catch(InputMismatchException excep1)
               {
                  String word = inputFile.next();
               }
               catch(NoSuchElementException excep2){
               }
            }
         }
      }
      return array;
   }

   public static void printArrayAndIntegerCount(Integer[] array, String filename) {
   //prints number of integers from file
   //prints each integer in array
   }
}

Assuming all you logic for reading integers from file are correct and also hoping this is kind of home work. 假设您从文件中读取整数的所有逻辑都是正确的,并且还希望这是一种家庭作业。 Though the following implementation is not the right approach, it just solves your purpose. 尽管以下实现不是正确的方法,但它只是解决了您的目的。 All we are doing here is iterating all the elements in the array until it reaches the null and keep writing them into a buffer. 我们在这里要做的就是迭代数组中的所有元素,直到它达到null为止,并继续将它们写入缓冲区。

public static void printArrayAndIntegerCount(Integer[] array, String filename) {
   StringBuilder sb = new StringBuilder();
   int count = 0;
   for(Integer i : array) {
      if(i != null) {
          count++;
          sb.append("index = ").append(i).append(", element = ").append(array[i]).append("\n");
      } else {
          break;
      }
   }
   System.out.println("number of integers in file \""+filename+"\" = "+count);
   System.out.println(sb);
}

Replace your catch statement with: 将您的catch语句替换为:

catch(InputMismatchException excep1)
{
      String word = inputFile.next();
      i-=1;
}

You were incrementing the array counter if it found a word . 如果发现一个单词,则要递增数组计数器 I have run my own test and this worked for me to fix your issue. 我已经进行了自己的测试,因此可以解决您的问题。

 public static void printArrayAndIntegerCount(Integer[] array, String filename) {
       String message = "";
       int i = 0;
       while(i < array.length && array[i]!=null){
           message = message + "index = "+i+", element = "+array[i]+"\n";
           i+=1;
        }
       System.out.println("number of integers in file \""+filename+"\" = "+i);
       System.out.println(message);
}

The approach taken in the first method is a bit flawed, since you're incrementing the i variable whether or not an integer is read. 第一种方法采用的方法有些缺陷,因为无论是否读取整数,都将递增i变量。

So for example, if the file looked like this: 因此,例如,如果文件如下所示:

4
Hello
5
e
7

The beginning of your array would look like 数组的开始看起来像

[4, null, 5, null, 7...]

So you will end up with an array of size 1000, which has nulls at unpredictable places in there. 因此,您将得到一个大小为1000的数组,该数组在其中不可预测的位置为null。

A slightly better approach would be this: 更好的方法是:

  • Keep a separate count variable that says how many integers you actually read. 保留一个单独的count变量,该变量表示您实际读取了多少个整数。
  • Add items to the array at index count and not at i (since i just says how many lines you've looked at, whereas count will tell you how many integers you've come across). 在索引count而不是在i处将项目添加到数组中(因为i只是说您已经看过多少行,而count会告诉您遇到了多少个整数)。
  • When you're finished reading them, either 当您读完它们后,
    • pass the count variable to the method that prints the array (so it knows only to look at the first count items), or count变量传递给打印数组的方法(因此它只知道第一个count项),或者
    • just copy the entire array into a new array of size count . 只需将整个数组复制到一个新的大小count数组中即可。

Example incorporating this into your code: 将其合并到您的代码中的示例:

if(inputFile != null) {
    // the number of integers we've read so far
    int count = 0;

    // loop through file for integers and store in array
    while(inputFile.hasNextLine()) {
        for(int i = 0; i < array.length; i++) {
            try {
                array[count] = inputFile.nextInt();
                count++;
            } catch(InputMismatchException excep1) {
                String word = inputFile.next();
            } catch(NoSuchElementException excep2) {
            }
         }
     }
}

Then to copy into a correctly sized array, 然后复制到正确大小的数组中,

Integer[] newArray = new Integer[count];
for(int i = 0; i < count; i++) {
    newArray[i] = array[i];
}

and just return newArray instead of array . 然后只返回newArray而不是array

Your print method will then simply have the same signature and functionality you'd expect: 然后,您的打印方法将具有与您期望的相同的签名和功能:

public static void printArrayAndIntegerCount(Integer[] array, String filename) {
    for(int i = 0; i < array.length; i++) {
        // print the number at array[i], and whatever else you want to print
    }
}

This is probably the better approach, as you can still keep all the method signatures the same, and don't need to mess around with returning multiple variables or changing global state. 这可能是更好的方法,因为您仍然可以使所有方法签名保持相同,并且无需弄乱返回多个变量或更改全局状态。


Or alternatively, if you don't want to copy the relevant bits into a new array, then you could just pass the count variable somehow to your second method, and do something like 或者,如果您不想将相关位复制到新数组中,则可以将count变量以某种方式传递给第二种方法,然后执行类似的操作

for(int i = 0; i < count; i++) {
    System.out.println("\tindex = " + i + ", element = " + array[i]);
}

Key difference there is you're iterating up to count , and not up to array.length . 关键的区别在于您要迭代count ,而不要迭代array.length

You would need to find a way to return that from your first method along with the array (or maybe set a static variable somewhere), and you would then need to change the signature of your second method to be 您将需要找到一种方法来从第一个方法连同数组(或者可能在某个地方设置静态变量)中将其返回,然后需要将第二个方法的签名更改为

public static void printArrayAndIntegerCount(Integer[] array, int count, String filename) {
    ...
}

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

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