2

This (title) is happening for some reason.

I have a text file like this:

5
H  H  H  H  H
V  H  H  H  H
H  X  X  X  X
H  D  H  H  H
H  H  H  H  X

I parsed the file with

input.useDelimiter(" ");

I read in and store the number on line 1 in a variable named "size"

Then I proceeded to read the file with a nested loop and stored the elements in a 2D array:

    for(int x = 0; x < size; x++) {
        for (int y = 0; y < size; y++) {
            maze[x][y] = input.next();
            System.out.print(maze[x][y] + " ");
        }
    }

For some reason, the last element of a line and the first element of the next line is always read together, with a newline in between. So maze[0][4] stores H\nV, when it's only supposed to store H.

I'm clueless about why this is happening.

EDIT: I noticed the problem goes away after I add a space at the end of each line in the text file, but is there a way to fix this issue w/o altering the file?

cplusalex
  • 83
  • 4

1 Answers1

2

Your input delimiter is a blank space. When your file is split, it splits all actual spaces as delimiters and cuts them. But the newline character (depending whatever OS/encoding you are using) is interpreted as what it is, and not as a whitespace.

You can either write all elements into one line and parse the file as oneliner, or better, you can first split the file by lines (delimiter "\n" or "\r" or whatever) and then you can split it by whitespaces. However my goto would be a regular expression matcher, because those do a good job in this regard.

Pattern pattern = Pattern.compile("[^\\h\\v]+");
Matcher matcher = pattern.matcher(input); // cut the matrix size before you do this!
int x = 0;
int y = 0;
while (matcher.find()) {
    String match = matcher.group(0);
    maze[x][y] = match;
    ++y;
    if (y == size) {
        ++x;
        y = 0;
    }
}

The pattern [^\\v\\h]+ captures anything non-whitespace or line break (non-vertical or horizontal whitespaces). In other words, it splits your string by what you want it to be split. However a regex matcher works a bit differently than split. It allows you to interpret each match individually, even with substrings within your match, if you define them in the expression. https://www.vogella.com/tutorials/JavaRegularExpressions/article.html

TreffnonX
  • 2,924
  • 15
  • 23
  • 1
    I've never seen the `\h` escape sequence in Java, and the `*` in the regular expression might match an empty string. That sounds wrong too. – Roland Illig Apr 29 '19 at 05:44
  • You are partially right. I changed it to "+", which matches positive number of characters (more than 0). However the \v and \h do work. They are part of the javadoc for regular expressions. They just appear a bit down the definition: Predefined character classes (Unicode character) \h A horizontal whitespace \H A non horizontal whitespace \v A vertical whitespace \V A non vertical whitespace https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html – TreffnonX Apr 29 '19 at 05:47
  • Did you try to compile this code? As it stands, the `\h` is an escape sequence for a Java string and not an escape sequence for a regular expression. You need to write double backslashes. – Roland Illig Apr 29 '19 at 05:51