我有以下代码尝试确定文件的尺寸,但是每次执行时都会出现此错误:
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()
将行读入一个字符串,称为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();
}
}