Мой код считывает последнюю переменную в строке и первую переменную в следующей строке (в текстовом файле) как один элемент?

Это (название) происходит по какой-то причине.

У меня есть такой текстовый файл:

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

Я проанализировал файл с

input.useDelimiter(" ");

Я читаю и сохраняю число в строке 1 в переменной с именем «размер».

Затем я приступил к чтению файла с помощью вложенного цикла и сохранил элементы в двумерном массиве:

    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] + " ");
        }
    }

По какой-то причине последний элемент строки и первый элемент следующей строки всегда читаются вместе с новой строкой между ними. Таким образом, maze[0][4] хранит H\nV, когда предполагается хранить только H.

Я понятия не имею, почему это происходит.

РЕДАКТИРОВАТЬ: я заметил, что проблема исчезает после добавления пробела в конце каждой строки в текстовом файле, но есть ли способ исправить эту проблему без изменения файла?


person cplusalex    schedule 29.04.2019    source источник
comment
дай свой полный код   -  person Mukit09    schedule 29.04.2019


Ответы (1)


Ваш разделитель ввода - это пробел. Когда ваш файл разделен, он разделяет все фактические пробелы в качестве разделителей и обрезает их. Но символ новой строки (в зависимости от того, какую ОС/кодировку вы используете) интерпретируется как то, что он есть, а не как пробел.

Вы можете либо записать все элементы в одну строку и разобрать файл как oneliner, или, что еще лучше, вы можете сначала разделить файл по строкам (разделитель "\n" или "\r" или что-то еще), а затем вы можете разделить его по пробелам. Однако мой goto будет сопоставлением регулярных выражений, потому что они хорошо справляются с этой задачей.

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

Шаблон [^\\v\\h]+ захватывает все, что не является пробелом или разрывом строки (не вертикальным или горизонтальным пробелом). Другими словами, он разбивает вашу строку на то, что вы хотите, чтобы она была разделена. Однако сопоставление регулярных выражений работает немного иначе, чем расщепление. Это позволяет вам интерпретировать каждое совпадение индивидуально, даже с подстроками в вашем совпадении, если вы определяете их в выражении. https://www.vogella.com/tutorials/JavaRegularExpressions/article.html

person TreffnonX    schedule 29.04.2019
comment
Я никогда не видел управляющую последовательность \h в Java, а * в регулярном выражении может соответствовать пустой строке. Это тоже звучит неправильно. - person Roland Illig; 29.04.2019
comment
Вы частично правы. Я изменил его на +, что соответствует положительному количеству символов (более 0). Однако \v и \h работают. Они являются частью javadoc для регулярных выражений. Они просто появляются немного ниже определения: Предопределенные классы символов (символ Unicode) \h Горизонтальный пробел \H Негоризонтальный пробел \v Вертикальный пробел \V Невертикальный пробел docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html< /а> - person TreffnonX; 29.04.2019
comment
Вы пытались скомпилировать этот код? В нынешнем виде \h — это escape-последовательность для строки Java, а не escape-последовательность для регулярного выражения. Вам нужно написать двойную обратную косую черту. - person Roland Illig; 29.04.2019