- Строки — Основы Java
- Экранирующие последовательности
- Конкатенация
- Дополнительные материалы
- Остались вопросы? Задайте их в разделе «Обсуждение»
- Открыть доступ
- Как добавить перенос строки в Java
- Как сделать перенос строки
- Способ первый – захардкодить перенос строки
- Способ второй – портабельный и правильный
- Чем отличается «\r» от «\n» в языке Java?
Строки — Основы Java
Какие из этих пяти вариантов — строки? С первыми двумя все понятно: это точно строки, мы уже работали с подобными конструкциями. А что насчет остальных?
Любой одиночный символ в кавычках — это строка. Пустая строка «» — это тоже строка. То есть строкой мы считаем все, что находится внутри кавычек, даже если это пробел, один символ или вообще отсутствие символов.
Представьте, что вы хотите напечатать строчку dragon’s mother. Апостроф перед буквой s — это такой же символ, как одинарная кавычка. Попробуем. Такой вариант программы отработает корректно:
System.out.println("Dragon's mother");
А что, если мы хотим создать такую строку:
В ней есть и одинарные, и двойные кавычки. Как быть в этой ситуации? Если просто попытаться вывести такую строку, то мы получим ошибку:
// Завершится с синтаксической ошибкой System.out.println("Dragon's mother said "No"");
С точки зрения Java, здесь странная конструкция из трех компонентов:
- Строки «Dragon’s mother said «
- Строки «»
- Слово No между ними, которое не рассматривается как строка, потому что оно не в кавычках
Привычным способом эту строчку не вывести. Для вывода таких строк используют символ экранирования: \ .
Если поставить \ перед кавычкой, это будет означать, что кавычку нужно рассматривать не как начало или конец строки, а как ее часть:
System.out.println("Dragon's mother said \"No\"");
Экранирующие последовательности
Мы хотим показать диалог Матери Драконов со своим ребенком:
Если вывести на экран строку с таким текстом:
System.out.println("- Are you hungry?- Aaaarrrgh!");
Не то, что мы хотели. Строки расположены друг за другом, а не одна ниже другой. Нам нужно как-то сказать интерпретатору «нажать на Enter» — сделать перевод строки после вопросительного знака. Это можно сделать, используя символ перевода строки: \n :
System.out.println("- Are you hungry?\n- Aaaarrrgh!");
\n — это специальный символ. В литературе его часто обозначают как LF (Line Feed). Возможно, вы сейчас подумали, что это опечатка, ведь здесь мы видим два символа \ и n , но это не так. С точки зрения компьютера — это один невидимый символ перевода строки:
// Мы это не изучали, но вы должны знать правду // Ниже код, который возвращает длину строки "a".length(); // 1 "\n".length(); // 1 . "\n\n".length(); // 2 .
Почему так сделано? \n — всего лишь способ записать символ перевода строки, но сам перевод строки по своему смыслу – это один символ, правда, невидимый.
Именно поэтому и возникла такая задача. Нужно было как-то представить его на клавиатуре. А поскольку количество знаков на клавиатуре ограничено и отдано под самые важные, то все специальные символы реализуются в виде таких обозначений.
Символ перевода строки не является чем-то специфичным для программирования. Все, кто хоть раз печатал на компьютере, использовал перевод строки, нажимая на Enter.
Во многих редакторах есть опция, позволяющая включить отображение невидимых символов. Эта опция помогает понять, где они находятся, хотя это всего лишь схематичное отображение, ведь у этих невидимых символов нет графического представления:
Устройство, которое выводит соответствующий текст, учитывает этот символ. Например, принтер при встрече с LF протаскивает бумагу вверх на одну строку, а текстовый редактор переносит весь последующий текст ниже, также на одну строку.
\n — это пример экранирующей последовательности (escape sequence). Их еще называют управляющими конструкциями. Хотя таких символов не один десяток, в программировании часто встречаются всего несколько.
Кроме перевода строки, к таким символам относятся:
- Табуляция — разрыв, получаемый при нажатии на кнопку Tab
- Возврат каретки (только в Windows)
Программистам часто нужно использовать перевод строки \n для правильного форматирования текста:
System.out.println("Gregor Clegane\nDunsen\nPolliver\nChiswyck");
Обратите внимание на следующие моменты:
- Не имеет значения, что стоит перед или после \n : символ или пустая строка. Перевод будет обнаружен и выполнен в любом случае
- Помните, что строка может содержать один символ или вообще ноль символов. А еще строка может содержать только \n . Проанализируйте следующий пример:
System.out.println("\n"); System.out.println("Dunsen");
Здесь мы сначала выводим строку «перевод строки», а потом делаем вывод обыкновенной строки. Программа выведет на экран:
Почему перед строкой Dunsen появилось две пустые строки, а не одна? Дело в том, что System.out.println() при выводе значения автоматически добавляет в конец символ перевода строки. Таким образом, один перевод строки мы указали явно, передав этот символ экранирующей последовательности аргументом в функцию, а второй перевод строки добавлен самой функцией автоматически. Еще пример кода:
System.out.println("Polliver"); System.out.println("Gregor Clegane"); System.out.println(); System.out.println("Chiswyck\n"); System.out.println("Dunsen");
System.out.println("Joffrey loves using \\n");
Небольшое, но важное замечание про Windows. В Windows для перевода строк по умолчанию используется \r\n — это связано с историческими причинами. Такая комбинация хорошо работает только в Windows, но создает проблемы при переносе в другие системы: например, когда в команде разработчиков есть пользователи как Windows, так и Linux.
Дело в том, что последовательность \r\n имеет разную трактовку в зависимости от выбранной кодировки. Поэтому в среде разработчиков принято всегда использовать \n без \r , так как LF всегда трактуется одинаково и отлично работает в любой системе. Не забудьте настроить ваш редактор на использование \n .
Конкатенация
Программы постоянно оперируют строками. Все, что мы видим на сайтах или в мобильных приложениях, так или иначе представлено в виде текста. Этот текст чаще всего динамический — полученный из разных частей, которые соединяются вместе. Операция соединения строк в программировании называется конкатенацией и выглядит так:
// Оператор такой же, как и при сложении чисел, // но здесь он имеет другой смысл (семантику) System.out.println("Dragon" + "stone"); // => Dragonstone
Склеивание строк всегда происходит в том же порядке, в котором записаны операнды. Левый операнд становится левой частью строки, а правый — правой. Вот еще несколько примеров:
System.out.println("Kings" + "wood"); // => Kingswood // Обратный порядок слов System.out.println("road" + "Kings"); // => roadKings // Конкатенировать можно абсолютно любые строки System.out.println("King's" + "Landing"); // => King'sLanding
В последнем примере название города получилось с ошибкой: King’s Landing нужно писать через пробел. Но в наших начальных строках не было пробелов, а пробелы в самом коде вокруг символа + не имеют значения, потому что они не являются частью строк.
Из этой ситуации есть три выхода:
// Ставим пробел в левой части System.out.println("King's " + "Landing"); // => King's Landing // Ставим пробел в правой части System.out.println("King's" + " Landing"); // => King's Landing // Добавляем пробел отдельно System.out.println("King's" + " " + "Landing"); // => King's Landing
Пробел — такой же символ, как и другие. Чем больше пробелов, тем шире отступы:
System.out.println("King's " + " Landing"); // => King's Landing System.out.println("King's " + " Landing"); // => King's Landing
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Об обучении на Хекслете
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Как добавить перенос строки в Java
Перенос строки, он же перенос каретки это один или несколько спецсимволов, означающие окончание текущей строки символов и перевод картеки на новую строку. В зависимости от операционной системы используются разные спецсимволы. Например, в Windows используются спецсимволы CR + LF:
Спецсимолы | Альт-код | Управляющая последовательность | Операционные системы |
---|---|---|---|
CR LF | 13 10 | \r \n | DOS, OS/2, все версии Windows (в том числе и последние) |
LF | 10 | \n | Linux, macOS, Unix и прочие POSIX-совместимые системы |
CR | 13 | \r | Старые версии Mac OS (до версии 9) |
Спецсимволу CR соответсвует альт-код 13, а спецсимволу LF альт-код 10. Кстати, CR означает carriage return (возврат каретки), а LF это line feed (перевод строки). Управляющая последовательность \r\n или \n как раз и обозначает перевод строки в Си подобных языках программирования.
Как сделать перенос строки
Допустим, у вас есть строка, содержимое которой выводится в консоль:
String oneLine = "Hello Java World!"; System.out.println(oneLine);
При выводе в консоль вы увидите те же слова, составляющие ровно одну строку, без переносов на новые строки. Как же нам добавить перенос строки в Java?
Для разных операционных систем переносом строки являются разные управляющие символы:
Для Windows это символы \r\n
Для Linux, macOS и прочих *nix систем это \n
Нужно добавить в искомую строку нужную управляющую последовательность, в зависимости от того, в какой операционной системе выолняется ваша программа.
Способ первый – захардкодить перенос строки
Допустим, ваша программа на Java запускается в Linux. Вы просто добавляете символы \n в то место в строке, в котором вам нужно сделать перевод на новую строку:
String multipleLines = "Hello\nJava\nWorld!"; System.out.println(multipleLines);
Теперь, при использовании переносов строки, вы, вместо одной строки в консоли увидите три строки – по каждой на символы \n
Но как же быть, если вы не хотите хардкодить символы переноса строки?
Способ второй – портабельный и правильный
Если вы не хотите писать символы \n каждый раз, когда хотите сделать перенос строки – вы можете воспользоваться стандартным методом System.lineSeparator() , который возвращает перенос строки для той операционной системы, в которой сейчас выполняется ваша программа. Это очень полезно, если программа исполняется и в Windows и в Linux окружении.
Просто используйте System.lineSeparator() в том месте, где вам нужно создать новую строку:
String multipleLines = "Hello" + System.lineSeparator() + "Java" + System.lineSeparator() + "World!"; System.out.println(multipleLines);
Итак, вы научились делать перевод строки в Java, используя два способа.
Чем отличается «\r» от «\n» в языке Java?
Имеються в виду esc-последовательности для форматирования текста.
Пример:
1) System.out.print(«хз \r хз»);
Выдаёт:
хз
хз
2) System.out.print(«хз \n хз»);
Выдаёт:
хз
хз
Хоть убейте — не могу понять в чём разница!
В учебнике написано:
«\r — возврат каретки
\n — перевод строки»
Чем «Возврат коретки» отличается от обычного перевода строки?
Допустим вот такое
System.out.print(«ABCDEFG\r1234»);
выдаст
1234EFG
т. е. возврат каретки на исходную позицию в этой же строке.
А вот такое
System.out.print(«ABCDEFG\n1234»);
выдаст
ABCDEFG
1234
т. е. переход на новую строку.
а ваш пример
System.out.print(«хз \r хз»);
должен выбать
хз
(именно с пробелом перед «хэ»
и именно один раз.
Возврат каретки (англ. carriage return, CR) — управляющий символ ASCII (0x0D, 13 в десятичной системе счисления, ‘\r’), при выводе которого курсор перемещается к левому краю поля, не переходя на другую строку. Этот управляющий символ вводится клавишей «Enter». Будучи записан в файле, в отдельности рассматривается как перевод строки только в системах Macintosh.
Подача строки (от англ. line feed, LF — «подача [бумаги] на строку» ) — управляющий символ ASCII (0x0A, 10 в десятичной системе счисления, ‘\n’), при выводе которого курсор перемещается на следующую строку. В случае принтера это означает сдвиг бумаги вверх, в случае дисплея — сдвиг курсора вниз, если ещё осталось место, и прокрутку текста вверх, если курсор находился на нижней строке. Возвращается ли при этом курсор к левому краю или нет, зависит от реализации.
LF (ASCII 0x0A) используется в Multics, UNIX, UNIX-подобных операционных системах (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD и др.) , BeOS, Amiga UNIX, RISC OS и других;
CR (ASCII 0x0D) используется в 8-битовых машинах Commodore, машинах TRS-80, Apple II, системах Mac OS до версии 9 и OS-9;
CR+LF (ASCII 0x0D 0x0A) используется в DEC RT-11 и большинстве других ранних не-UNIX- и не-IBM-систем, а также в CP/M, MP/M (англ.) , MS-DOS, OS/2, Microsoft Windows, Symbian OS, протоколах Интернет.
Александр привел несоответствующий действительности пример, т. к. при написании System.out.print(«ABCDEFG\r1234»); выведет не 1234EFG, а
ABCDEFG
1234
Java покажет похожие результаты и дело, на самом деле, не в ней, а в платформе, которую вы используете!
\n для unix
\r для mac
\r\n для Windows