【问题标题】:Read text file for integers and storing to array using scanner and exceptions使用扫描仪和异常读取整数的文本文件并存储到数组
【发布时间】:2014-02-14 21:04:57
【问题描述】:

我正在尝试循环遍历整数的文本文件并将找到的整数存储到数组中。

使用 try-catch 来确定哪些单词是整数,哪些不是使用 InputMismatchException,从输入流中删除非整数字符串。以及文件中空行的 NoSuchElementException。 我的主要问题是在我的第二种方法中存储整数并在数组中打印这些整数 :o 。看来我的循环也将非整数记录为空。他们不应该被存储到数组中。

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
   }
}

【问题讨论】:

  • 您是否允许使用List 而不是Array,因为您的数组长度在此处始终为1000,并且很难说出您实际存储在该数组中的整数数量。
  • 遗憾的是没有列表,尽管这会使事情变得更容易。我需要使用一个数组:o

标签: java arrays exception file-io java.util.scanner


【解决方案1】:

假设你从文件中读取整数的所有逻辑都是正确的,并且希望这是一种家庭作业。尽管以下实现不是正确的方法,但它只是解决了您的目的。我们在这里所做的只是迭代数组中的所有元素,直到它到达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);
}

【讨论】:

  • 嗯,我尝试实施您的建议和 Sowrinator 的建议,但最终得到 ArrayIndexOutOfBoundsException。是否可以对循环进行调整以不将空值存储到数组中?
  • 当你初始化Integer[]时,默认数组会被初始化为空值。你可以有一个int[],它默认为0,并遵循彼得的方法。
【解决方案2】:

将你的 catch 语句替换为:

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

如果数组计数器找到了一个单词,则它会递增。我已经运行了自己的测试,这对我解决您的问题很有用。

 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);
}

【讨论】:

  • 这似乎与我正在寻找的输出相匹配。虽然,你知道我可以做些什么来不将整数(空值)存储到我的数组中吗?
【解决方案3】:

第一种方法中采用的方法有点缺陷,因为无论是否读取整数,您都在递增 i 变量。

例如,如果文件看起来像这样:

4
Hello
5
e
7

数组的开头看起来像

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

所以你最终会得到一个大小为 1000 的数组,其中在不可预知的地方有空值。

稍微好一点的方法是这样的:

  • 保留一个单独的 count 变量来说明您实际读取了多少个整数。
  • 将项目添加到数组的索引count 而不是i(因为i 只是表示您查看了多少行,而count 会告诉您遇到了多少个整数)。
  • 读完之后,
    • count 变量传递给打印数组的方法(因此它只知道查看第一个count 项),或者
    • 只需将整个数组复制到一个大小为count 的新数组中。

将其合并到您的代码中的示例:

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) {
            }
         }
     }
}

然后复制到正确大小的数组中,

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

只返回newArray 而不是array

然后,您的打印方法将具有您期望的相同签名和功能:

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
    }
}

这可能是更好的方法,因为您仍然可以保持所有方法签名相同,并且不需要返回多个变量或更改全局状态。


或者,如果您不想将相关位复制到新数组中,那么您可以以某种方式将 count 变量传递给您的第二种方法,然后执行类似的操作

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

关键区别在于您迭代到 count,而不是到 array.length

你需要找到一种方法从你的第一个方法中返回它以及数组(或者可能在某处设置一个静态变量),然后你需要将你的第二个方法的签名更改为

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

【讨论】:

  • 嗯,我了解您的流程。但在我的第二种方法中似乎找不到计数?
  • 嗯,就像我怎样才能使“count”= 到一个新数组并返回该数组,所以我可以在我的第二种方法中打印它:o?
  • 只需将 count 作为参数添加到您的第二种方法,然后将其从您的第一种方法传递到那里。但如果你使用第一种方法会更好(见我上面的编辑)
  • 我尝试用 return newArray 代替 return 数组,但我的打印方法会是什么样子?因为我不会使用“计数”?很抱歉给您添麻烦
  • 您的打印方法将完全相同 - 它不会知道有关 count 或 newArray 的任何信息。它所关心的只是它将给出的数组的长度表示其中有多少实际数字。更新答案以反映这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-13
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
相关资源
最近更新 更多