簡體   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