我有以下代码尝试确定文件的尺寸,但每次执行时都会出现此错误:
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++;
}
答案 0 :(得分:4)
您在扫描循环中根本没有为变量分配数据,不仅仅是这样,而是从扫描器两次读取数据,而只检查一次 ,这是一件危险的事情。
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();
我会:
fileScanner.hasNextLine()
,然后调用nextLine()
将行读入字符串,称为line
。lineScanner.hasNext()
循环,并将数据读入您的变量。或者,您可以使用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();
}
}