Неверное отображение русских символов

Sergey_A

Возникла необходимость работы через консоль с русским буквами. Код такой:

Scanner sc = new Scanner(System.in,"cp866");
System.setProperty("console.encoding","cp866");
PrintStream ps = new PrintStream(System.out);
ps.println("Введите условия задачи");
String taskText=sc.nextLine();
ps.println("Мы получили текст: "+taskText);

В результате у меня получается примерно следующее:

Введите условия задачи
на дворе трава, на траве дрова12
Мы получили текст: ?? ????? ?????, ?? ????? ?????12

С кодировками экспериментировал, не помогло.

2 ответа

Sergey_A

Раз вопрос всплыл, отвечу на него.

Ваша проблема в том, что "консоль" Netbeans - и консоль ОС - это немного разные вещи. В частности, у них отличаются используемые кодировки. Оптимальным было бы получение текущей кодировки консоли через Console API - но Java такого не предоставляет. Поэтому надо получить информацию о консольной кодировке другим способом. К примеру, через свойство console.encoding.

Способ 1

Для начала, установка свойства console.encoding в предопределенное значение ничего не дает. Это свойство попросту никем не читается. Вместо того, чтобы ставить его в cp866, следовало бы, напротив, прочитать из него значение.

String encoding = System.getProperty("console.encoding", "utf-8");
Scanner sc = new Scanner(System.in, encoding);
PrintStream ps = new PrintStream(System.out, encoding);

Таким образом, вместо того, чтобы ожидать ввода в cp866, программа позволяет запустившему ее указать любую кодировку (utf-8 - это кодировка по умолчанию. Замените ее на ту, которую использует консоль NetBeans). Запускать программу надо будет как-то так:

java -Dconsole.encoding=cp866 ...

На первый взгляд, такой способ запуска кажется сложным. Но обычно для запуска "серьезных" программ на Java всегда используется некоторый пакетный файл. Что мешает дописать этот ключ в него?

И не забывайте, консоль в Windows может оказаться в любой кодировке! К примеру, некоторые программы, такие как reg.exe, умеют работать с консолью только в windows-1251. Умение выводить в любой кодировке может пригодиться.

chcp 1251
reg ...

java -Dconsole.encoding=windows-1251 ...

Способ 2

Если уже заговорили про пакетные файлы, то есть более простой способ, хотя и не такой мощный. Можно просто сменить кодировку консоли на нужную перед запуском программы:

chcp 1251
java ...

Вот номера кодовых страниц Windows, которые могут пригодиться:

  • 866 - cp866
  • 1251 - windows-1251
  • 65001 - кодировка utf-8
  • 1200 - двухбайтовая кодировка utf-16

PS

Помните, что System.in и System.out, как правило, всегда должны быть в одной и той же кодировке. У вас в исходной программе сканер читал из System.in в кодировке cp866 - а принтер выводил в System.out в кодировке по умолчанию. Такое несоответствие - тоже источник ошибок. Никогда так не делайте.


Sergey_A

Измените кодировку на UTF-8:

Scanner sc = new Scanner(<a href="http://System.in" target="_blank">System.in</a>,"utf-8");
System.setProperty("console.encoding","utf-8");
...

Отметьте, что кодировка UTF-8 используется по умолчанию. Можно просто писать так:

Scanner sc = new Scanner(<a href="http://System.in" target="_blank">System.in</a>);
PrintStream ps = new PrintStream(System.out);
ps.println("Введите условия задачи");
...

licensed under cc by-sa 3.0 with attribution.