繁体   English   中英

将文件读入2D数组时出错

[英]Error when reading file into 2D array

我有以下代码尝试确定文件的尺寸,但是每次执行时都会出现此错误:

Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)

我不知道为什么会这样。 谁能帮助调试问题? 并解释为什么会这样吗?

public void loadDistances(String fname) throws Exception {
    String file = fname;
    File f = new File(file);
    Scanner in = null;

    try {
        in = new Scanner(f);
    }
    catch (FileNotFoundException ex) {
        System.out.println("Can't find file " + file);
        System.exit(1);
    }

    int rows = 0;
    int cols = 0;
    int elements = 0;

    while(in.hasNext()){ 
        while(in.next() != null){
            System.out.println(elements++);
        }
        in.nextLine(); 
        rows++;
    }
    in.close();

    cols = (elements + 1) / rows;

    // for debug purposes
    System.out.println(rows);
    System.out.println(cols);
}

哪个读入此文件

0 2 3.0
1 0 2.0
2 1 7.0
2 3 1.0
3 0 6.0

//检查建议的答案

    int tokens = 0;
    String line;
    Scanner tokenScanner;
    Scanner fileScanner;
    Scanner lineScanner;

    while(fileScanner.hasNextLine()){
        line = fileScanner.nextLine();
        lineScanner.nextLine() = line;
        while(lineScanner.hasNext()){
            tokens++;
        }
        rows++;
    }

您不仅没有在扫描循环中为变量分配任何数据,而且不仅如此,而且在仅一次扫描一次以检查数据的情况下从扫描器读取了两次 ,这很危险。

while(in.hasNext()){                 // **** checking once ****
    while(in.next() != null){        // **** read in and waste a token here!
        System.out.println(elements++);
    }
    in.nextLine();   // **** read in and waste a line here
    rows++;
}
in.close();

我会:

  • 使用两个Scanner变量,其中一个为fileScanner,以读取文件中每一行文本,...
  • 一个叫lineScanner的人读入行中的每个令牌。
  • 我将使用一个外部while循环,该循环检查fileScanner.hasNextLine() ,然后调用nextLine()将该行读入一个String中,称为line
  • 然后,我将使用创建的String行创建一个新的Scanner,并将其分配给lineScanner变量。
  • 我将使用一个内部while循环,该循环在lineScanner.hasNext()时循环,并将数据读入您的变量中。
  • 我将在外部while循环的末端关闭内部lineScanner,以免浪费资源。

或者,您可以使用String#split(...)在读入的行中拆分标记,然后将字符串解析为数字。 例如,

public List<RowData> loadDistances(String fname)
     throws FileNotFoundException, NumberFormatException {
  File file = new File(fname);
  Scanner fileScanner = new Scanner(file);
  List<RowData> rowList = new ArrayList<RowData>();

  while (fileScanner.hasNextLine()) {
     String line = fileScanner.nextLine();
     String[] tokens = line.split("\\s+");
     if (tokens.length != 3) {
        // throw some custom exception
     }

     int rowNumber = Integer.parseInt(tokens[0].trim());
     int xData = Integer.parseInt(tokens[1].trim());
     double yData = Double.parseDouble(tokens[2].trim());
     rowList.add(new RowData(rowNumber, xData, yData));
  }

  if (fileScanner != null) {
     fileScanner.close();
  }

  return rowList;
}

编辑
通过使用行扫描程序,我建议创建第二个扫描程序,传入从第一个扫描程序获得的行,并从第二个扫描程序中提取数据。 如果您不知道期望多少个令牌,可以使用while循环,但是您的数据似乎定义良好,每行包含一个int,int和double,我们可以使用此信息来帮助我们提取适当的数据。 您可以使用类似以下的代码:

 // use previous same code as above except in the while loop:
 while (fileScanner.hasNextLine()) {
     String line = fileScanner.nextLine(); // get line
     Scanner lineScanner = new Scanner(line);  // create Scanner with it
     int rowNumber = 0;
     int xData = 0;
     double yData = 0.0;

     if (lineScanner.hasNextInt()) {
        rowNumber = lineScanner.nextInt();
     } else {
        // throw a custom exception since int not found
     }
     if (lineScanner.hasNextInt()) {
        xData = lineScanner.nextInt();
     } else {
        // throw a custom exception since int not found
     }
     if (lineScanner.hasNextDouble()) {
        yData = lineScanner.nextDouble();
     } else {
        // throw a custom exception since double not found
     }

     rowList.add(new RowData(rowNumber, xData, yData));

     if (lineScanner != null) {
        lineScanner.close();
     }
  }

暂无
暂无

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

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