问题
I'm making a program that draws a basic image using instructions from a text file. The format for the instructions is:
SIZE 1000 500
// GROUND
LINE 0 350 1000 350
LINE 0 351 1000 351
LINE 0 352 1000 352
LINE 0 353 1000 353
and this is my code:
public void start(Stage stage) {
int fwidth = 0;
int fheight = 0;
try {
Scanner obj = new Scanner(new File("scene.txt"));
while(obj.hasNextLine()){
String str = obj.nextLine();
if(str.contains("SIZE")){
String a = "SIZE";
obj.skip(a);
System.out.println('b');
fwidth = obj.nextInt();
fheight = obj.nextInt();
}
if(str.contains("LINE")){
obj.skip("LINE");
System.out.println('a');
}
}
this is giving a NoSuchElementException. I'm assuming it's because the fwidth and fheight are taking the leading strings as ints but i can't figure out how to get the scanner to skip the strings at the beginning and just read the numbers once it knows what type of instruction it is. Any help is appreciated
回答1:
A couple suggestions:
First, I don't think
Scanner.skip()
does what you think it does. The purpose the .skip() method is to tell the scanner to "skip" lines at the time they are read, not to skip the line you are currently on. This will be done anyways the next time you call .nextLine().
I would remove all of your calls to .skip() entirely. Also, and this is more of a preference, but I would use a switch statement instead of multiple ifs. It makes your code more readable.
Secondly, as mentioned by Johnny in the comments, using .split() would probably be better since in my experience .nextInt() can produce unexpected results. So, your code would look like this:
while(obj.hasNextLine()){
String[] strArray = obj.nextLine().split(" ");
switch(strArray[0]){
case "SIZE":
fwidth = Integer.parseInt(strArray[1]);
fheight = Integer.parseInt(strArray[2]);
break;
case "LINE":
//do nothing
break;
}
}
回答2:
You can do it more easily as follows:
String str = obj.nextLine();
String[] arr = str.split("\\s+");// Split on whitespace
if("SIZE".equals(arr[0])) {
fwidth = Integer.parseInt(arr[1]);
fheight = Integer.parseInt(arr[2]);
} else if("LINE".equals(arr[0])) {
//...
}
回答3:
As mentioned in comments, you can use obj.next()
to scan line word by word rather than using nextLine()
:
Scanner obj = new Scanner(new File("scene.txt"));
int fwidth, fheight;
int num1, num2, num3, num4;
while(obj.hasNextLine() && obj.hasNext()){
String str = obj.next();
if(str.contains("SIZE")){
String a = "SIZE";
fwidth = obj.nextInt();
fheight = obj.nextInt();
System.out.println("fwidth : " + fwidth + ", fheight : " + fheight);
} else if(str.contains("LINE")){
num1 = obj.nextInt();
num2 = obj.nextInt();
num3 = obj.nextInt();
num4 = obj.nextInt();
System.out.println("num1 : " + num1 + ", num2 : " + num2 + ", num3: " + num3 + ", num4: " + num4);
}
}
I tested this with file you provided and it seemed to work:
src : $ java ScannerLeading
b
fwidth : 1000, fheight : 500
num1 : 0, num2 : 350, num3: 1000, num4: 350
num1 : 0, num2 : 351, num3: 1000, num4: 351
num1 : 0, num2 : 352, num3: 1000, num4: 352
num1 : 0, num2 : 353, num3: 1000, num4: 353
来源:https://stackoverflow.com/questions/64393459/how-to-skip-a-leading-string-when-scanning-text-file