Подтвердить что ты не робот

Печать Юникода из Scala интерпретатора

При использовании интерпретатора scala (т.е. выполнения команды 'scala' в командной строке) я не могу правильно печатать символы в Юникоде. Конечно, a-z, A-Z и т.д. Печатаются правильно, но, например, € или ƒ печатается как?.

print(8364.toChar)

приводит к? вместо €. Вероятно, я делаю что-то неправильно. Мой терминал поддерживает символы utf-8, и даже когда я передаю вывод в отдельный файл и открываю его в текстовом редакторе,?.

Это происходит в Mac OS X (Snow Leopard, 10.6.2) с scala 2.8 (ночная сборка) и Java 1.6.0_17)

4b9b3361

Ответ 1

Я нашел причину проблемы и решение, чтобы она работала должным образом. Поскольку я уже подозревал, что после публикации моего вопроса и чтения ответа Calum и вопросов с кодировкой на Mac с другим проектом (который был на Java), причиной проблемы является кодировка по умолчанию, используемая Mac OS X. Когда вы запускаете scala, он будет использовать кодировку по умолчанию для указанной платформы. В Mac OS X это Macroman, в Windows это, вероятно, CP1252. Вы можете проверить это, введя следующую команду в интерпретаторе scala:

scala> System.getProperty("file.encoding");
res3: java.lang.String = MacRoman

В соответствии с тестом scala help, можно предоставить свойства Java с использованием опции -D. Однако это не работает для меня. Я закончил установку переменной окружения

JAVA_OPTS="-Dfile.encoding=UTF-8"

После запуска scala результат предыдущей команды даст следующий результат:

scala> System.getProperty("file.encoding")
res0: java.lang.String = UTF-8

Теперь печать специальных символов работает как ожидалось:

print(0x20AC.toChar)               
€

Таким образом, это не ошибка в Scala, а проблема с кодировками по умолчанию. На мой взгляд, было бы лучше, если бы по умолчанию UTF-8 использовался на всех платформах. В моем поиске ответа, если это будет рассмотрено, я столкнулся с обсуждение в списке рассылки scala по этой проблеме. В первом сообщении предлагается использовать UTF-8 по умолчанию в Mac OS X, когда file.encoding сообщает Macroman, поскольку UTF-8 является кодировкой по умолчанию в Mac OS X (мне интересно, почему установлено значение file.encoding по умолчанию к Macroman, вероятно, это наследование от Mac OS до того, как было выпущено 10?). Я не думаю, что это предложение будет частью scala 2.8, так как Martin Odersky написал, что, вероятно, лучше всего держать вещи такими, какие они есть в Java (т.е. соблюдайте свойство file.encoding).

Ответ 2

Хорошо, по крайней мере, часть, если не все, вашей проблемы здесь состоит в том, что 128 не является кодовым кодом Unicode для евро. 128 (или 0x80, так как hex является нормой) U+0080 <control>, то есть это не печатный символ, поэтому неудивительно, что ваш терминал испытывает проблемы с его печатью.

Евро codepoint равен 0x20AC (или десятичным числом 8364), и это, похоже, работает для меня (я нахожусь в Linux, в ночное время 2.8):

scala> print(0x20AC.toChar)
€

Еще один забавный тест - напечатать символ снеговика Юникода:

scala> print(0x2603.toChar)
☃

128, поскольку, по-видимому, это расширенный символ с одной из кодовых страниц Windows.

Я получил другого персонажа, которого вы упомянули, чтобы работать тоже:

scala> 'ƒ'.toInt
res8: Int = 402

scala> 402.toChar
res9: Char = ƒ

Ответ 3

Для Windows в командной строке (cmd) print:

  • set JAVA_OPTS="-Dfile.encoding=UTF-8"
  • chcp 65001

Пункт 2 означает UTF-8

Если вы не хотите, чтобы каждый раз печатать "chcp 65001", вы можете изменить/добавить значение в реестре Windows следующим образом:

  • Запустить команду regedit
  • найти запись [HKEY_CURRENT_USER\Software\Microsoft\Command Processor]
  • New = > Строковое значение
  • Name = "AutoRun", Data = "chcp 65001" (без кавычек)

(см. https://superuser.com/a/482117/454417)

Я использую Windows 10 и scala 2.11.8