如何在扫描文本文件时跳过前导字符串?

huangapple go评论71阅读模式
英文:

How to skip a leading string when scanning text file?

问题

我正在制作一个程序,根据文本文件中的指令绘制基本图像。指令的格式如下:

SIZE 1000 500

// 地面
LINE 0 350 1000 350
LINE 0 351 1000 351
LINE 0 352 1000 352
LINE 0 353 1000 353

这是我的代码:

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');
            }
        }

这会导致 NoSuchElementException。我猜想这是因为 fwidth 和 fheight 将前面的字符串视为整数,但我无法弄清楚如何让扫描器在知道指令类型后跳过开头的字符串,然后只读取数字。感谢任何帮助。

英文:

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

得分: 1

你可以更简单地按以下方式进行:

String str = obj.nextLine();
String[] arr = str.split("\\s+"); // 按空格分割
if ("SIZE".equals(arr[0])) {
    fwidth = Integer.parseInt(arr[1]);
    fheight = Integer.parseInt(arr[2]);
} else if ("LINE".equals(arr[0])) {
    //...
}
英文:

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])) {
    //...
}

答案2

得分: 1

如评论中所述,您可以使用 obj.next() 逐个扫描单词,而不是使用 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);
    }
}

我使用您提供的文件进行了测试,似乎可以正常工作:

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
英文:

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

答案3

得分: 1

几个建议:

首先,我认为 Scanner.skip() 并不是你想的那样工作。skip() 方法的目的是在读取行时告诉扫描器“跳过”这些行,而不是跳过你当前所在的行。不管怎样,在下次调用 nextLine() 时都会执行这个操作。

我会完全删除你所有对 skip() 的调用。另外,这更多是一种偏好,但我会使用 switch 语句代替多个 if 语句。这会让你的代码更易读。

其次,正如 Johnny 在评论中提到的,使用 .split() 可能更好,因为根据我的经验,nextInt() 可能会产生意外的结果。所以,你的代码将会像这样:

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":
            // 什么都不做
            break;
    }
}
英文:

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;
                }
            }

huangapple
  • 本文由 发表于 2020年10月17日 01:00:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/64393459.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定