0

So I am trying to extract a piece of code from a txtfile ,the start of the piece being indicated by "# EMPIRES" and the end being indicated by another string starting with a '#'. My program however never finds the start of the piece and keeps on going until it reaches the end of the file.

To try and find out what the problem was I tried first to print every line that it finds. And here I encountered another problem. My code already stops finding new lines,long before "# EMPIRES" is even reached.

    public String getEmpirestxt(String fileName) {
    Scanner sc;
    try {
        sc = new Scanner(new File(fileName));
        String currentLine = sc.nextLine();
        StringBuilder empiresText = new StringBuilder(currentLine);
        while (!currentLine.startsWith("# EMPIRES")) {
            currentLine = sc.nextLine();
            System.out.println(currentLine);
        }
        currentLine = sc.nextLine();
        while (sc.hasNextLine() && currentLine.charAt(0)!='#') {
            empiresText.append("\n").append(sc.nextLine());
        }
        return empiresText.toString();
    } catch (FileNotFoundException ex) {
        System.out.println("Landed_Titles.txt not found.");
    }
    return null;
}

The textfile itself : https://www.wetransfer.com/downloads/a1093792d5ac54b6ccce04afecb9357f20140402095042/505fca

BURNS
  • 671
  • 1
  • 7
  • 17
  • Can you try to comment out "currentLine = sc.nextLine();"? And see if it works. – Boris Apr 02 '14 at 09:55
  • I am getting than stuck in the first loop since nothing changes... – BURNS Apr 02 '14 at 10:02
  • 1
    possible duplicate of [Java scanner not going through entire file](http://stackoverflow.com/questions/8330695/java-scanner-not-going-through-entire-file) – Max Meijer Apr 02 '14 at 10:16

5 Answers5

1
String currentLine = sc.nextLine();

you are starting reading from the next Line.

stinepike
  • 50,967
  • 14
  • 89
  • 108
  • The problem is located in the first whileloop since I get no errors with the code you posted. – BURNS Apr 02 '14 at 09:59
  • there is no compile time or runtime error .. this is a logical error . nextline reads from the next line .. so initially you are comparing from the second line – stinepike Apr 02 '14 at 10:40
1

Here is my solution to your problem. I used newBufferedReader instead of the Scanner to read the file. This example works with Java 7.

public String getEmpirestxt2(String fileName) {
    Charset charset = Charset.forName("ISO-8859-1");
    Path filePath = Paths.get(fileName);
    try (BufferedReader reader = Files.newBufferedReader(filePath, charset)) {
        String line = null;

        // find the start of the piece
        while ((line = reader.readLine()) != null && !line.equals(START)) {
        }
        System.out.println("START: " + line);

        // getting the piece
        StringBuilder sb = new StringBuilder();
        while ((line = reader.readLine()) != null && !line.startsWith(END)) {
            sb.append(line);
        }
        System.out.println("END: " + line);

        return sb.toString();
    } catch (IOException x) {
        System.err.format("IOException: %s%n", x);
    }
    return null;
}

The constants in the method are:

private static final String START = "# EMPIRES";
private static final String END = "#";

I tested it with your file and it works fine. It also prints the starting and end points of the required piece:

START: # EMPIRES
END: #      color={ 144 80 60 }
Boris
  • 16,422
  • 10
  • 42
  • 63
  • Your code works so THX! :) Just one remaining question ,there is nothing in your first while loop ,how come you dont get stuck into an eternal loop? – BURNS Apr 02 '14 at 11:29
  • In the first while loop it simply reads the file line by line. Because it's empty we simply ignore these lines. Eventually the reader will find the START and will exit the loop. This is a condition for iteration: !line.equals(START). When we hit START this condition becomes false and we exit the loop. – Boris Apr 02 '14 at 12:32
  • So the while control structure automatically goes to the next line? – BURNS Apr 02 '14 at 16:59
  • 1
    While statement continually executes a block of statements (in the above example it's empty, so nothing is happenning there) while a particular condition is true. Condition line = reader.readLine()); is reevaluated each iteration. Each iteration readLine() reads the next line. More info at: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html – Boris Apr 03 '14 at 09:50
0

The condition:

while (sc.hasNextLine() && currentLine.charAt(0)!='#')

may terminate even if the file has more lines to read, because of the second predicate. If currentLine.charAt(0)!='#' is fales, the while loop ends. This does not mean there are no more lines to read.

Harmlezz
  • 7,524
  • 23
  • 34
0

In your second while loop you never set currentLine

This part:

currentLine = sc.nextLine();
 while (sc.hasNextLine() && currentLine.charAt(0)!='#') {
     empiresText.append("\n").append(sc.nextLine());
 }

should be:

do{
    currentLine=sc.nextLine();
    empiresText.append("\n").append(sc.nextLine());
}while(sc.hasNextLine() && currentLine.charAt(0)!='#');

Otherwise the line right after # EMPIRES won't be read and the code while loop will never stop because the currentLine is not getting updated.

Max Meijer
  • 1,494
  • 1
  • 14
  • 22
  • Makes sense ,but since my code can't even get to the part where "# EMPIRES" starts I can't test your solution. – BURNS Apr 02 '14 at 10:14
0

Append currentLine instead of sc.nextLine() in the second while loop :

while (sc.hasNextLine() && currentLine.charAt(0) != '#') {
    empiresText.append("\n").append(currentLine);
    currentLine = sc.nextLine();
}

Otherwise you can use a single loop like below :

while (sc.hasNextLine()){
    if(sc.nextLine().startsWith("# EMPIRES")){
        currentLine = sc.nextLine();
        while (sc.hasNextLine() && currentLine.charAt(0) != '#') {
            empiresText.append("\n").append(currentLine);
            currentLine = sc.nextLine();
        }
    }
}
Rishav Basu
  • 401
  • 4
  • 11