Как убрать лишнюю пустую строку после добавления System.lineSeparator()?

public void write() {
    Scanner scan = new Scanner(System.in);
    StringBuilder newContent = new StringBuilder();
    String userClipboard = getUserClipboard();
        
    copyToClipboard(myFileContent);
        
    System.out.println("Enter content or edit old (paste it). To stop writing, enter \"quitprogram\":");
    String line;

    while (!(line = scan.nextLine()).equals("quitprogram")) {
        newContent.append(line).append(System.lineSeparator());
    }
        
    scan.close();
        
    copyToClipboard(userClipboard);

    notepad.writeContent(newContent.toString());
    System.out.printf("Successfully written!\n\nWritten content:\n%s", newContent);
}

Ошибка заключается в том, что из-за System.lineSeparator() после ввода всего текста создается пустая новая строка в конце, чего я бы не хотел видеть.
Но как это исправить, если System.lineSeparator() мне нужен для разделения строк?


Ответы (1 шт):

Автор решения: Nowhere Man

Если использовать StringBuilder как в начальном коде, то по большому счёту имеется два варианта:

  1. Удалить последний записанный перевод строки после цикла при помощи StringBuilder::delete(int start, int end):
String line;
StringBuilder newContent = new StringBuilder();
while (!"quitprogram".equals(line = scan.nextLine())) {
    newContent.append(line).append(System.lineSeparator());
}
newContent.delete(newContent.length() - System.lineSeparator().length(), newContent.length());

или просто уменьшить длину:

//...
newContent.setLength(newContent.length() - System.lineSeparator().length());
  1. Добавлять перевод строки внутри цикла только если newContent не является пустым:
String line;
StringBuilder newContent = new StringBuilder();
while (!"quitprogram".equals(line = scan.nextLine())) {
    newContent
        .append(newContent.length() > 0 ? System.lineSeparator() : "")
        .append(line);
}

Альтернативное решение: вместо StringBuilder использовать StringJoiner и его методы StringJoiner::add, StringJoiner::toString, что позволит избавиться от "ручного" управления соединением строк:

String line;
StringJoiner newContent = new StringJoiner(System.lineSeparator());
while (!"quitprogram".equals(line = scan.nextLine())) {
    newContent.add(line);
}
// ...
notepad.writeContent(newContent.toString());

Также хотелось бы отметить, что НЕ нужно вызывать метод scan.close() для экземпляра сканера, открытого на системном потоке ввода System.in, так как это приведёт к закрытию самого потока System.in, и следовательно дальнейшая обработка ввода из консоли станет невозможна (см. После Scanner.close() как работать со scanner?)

→ Ссылка