Консоль не принимает русские символы на ввод

Проблема с вводом через cmd: пишу примитивную java программу для теста кодировок(поймет ли русские символы). Код следующий:

import java.util.Scanner;
public class App {
    public static void main(String[] args) {
    System.out.println("Написано однажды, работает везде");
        Scanner console = new Scanner(System.in);
        System.out.print("Введите свое имя: ");
        System.out.println("Введенное имя: " + console.nextLine());
    }
}

И получаю следующий результат:

C:\>java App
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
Написано однажды, работает везде
Введите свое имя: Денис
Введенное имя:

То есть русские буквы терминал понимает, а вот принять на ввод их отказывается, иначе были бы хоть знаки вопроса.

Пытался ответить Nowhere Man, но не дает из-за рейтинга, потому дополняю вопрос. Строка Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 появляется, если лезть в переменные среды и указать системную переменную JAVA_TOOL_OPTIONS (где-то прочитал, что оно должно помочь). Для дальнейших тестов переменную эту я удалил. Так же была снята галка в региональных настройка "бета-версия:использовать юникод(utf-8)". Проведя аналогичные опыты получил следующее: введите сюда описание изображения


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

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

Удалось воспроизвести проблему, описанную в исходном вопросе, то есть, в консоли Win 10 Pro при установке кодовой страницы chcp 65001 будет получена "битая" строка байт, содержащая нули вместо кирилличных символов.

В моём случае нормальный вывод получался при использовании одинаковых кирилличных кодировок для ввода и вывода -- либо Win-1251, либо CP866.

Немного исправленный код:

import java.util.*;
import java.util.stream.*;

public class App2 {

    public static void main(String[] args) throws Exception {

        final String enc = System.getProperty("file.encoding");
        System.out.println(Locale.getDefault() + "/" + enc);
        
        System.out.println("привет");

        Scanner in = new Scanner(System.in, enc);
        String input;

        while(!"exit".equalsIgnoreCase(input = in.nextLine())) {
            System.out.println("> '" + input + "': " + hexBytes(input.getBytes(enc)));
        }
        System.out.println("----");
    }
    
    private static String hexBytes(byte ... arr) {
        return IntStream.range(0, arr.length)
            .map(i -> Byte.toUnsignedInt(arr[i]))
            .mapToObj(Integer::toHexString)
            .collect(Collectors.joining(" ", "[", "]"));
    }
}

Вывод (Windows-консоль CMD):

F:\SO>chcp 65001
Active code page: 65001

F:\SO>java App2
en_US/UTF-8
привет
Привет!
> '      !': [0 0 0 0 0 0 21]
одни нули...
> '         ...': [0 0 0 0 20 0 0 0 0 2e 2e 2e]
exit
----

F:\SO>chcp 1251
Active code page: 1251

F:\SO>java App2
en_US/UTF-8
привет
Привет!
> '??????!': [ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd 21]
пока
> '????': [ef bf bd ef bf bd ef bf bd ef bf bd]
exit
----

F:\SO>java -Dfile.encoding=windows-1251 App2
en_US/windows-1251
привет
Привет!
> 'Привет!': [cf f0 e8 e2 e5 f2 21]
всё ОК!
> 'всё ОК!': [e2 f1 b8 20 ce ca 21]
exit
----

F:\SO>chcp 866
Active code page: 866

F:\SO>java -Dfile.encoding=windows-1251 App2
en_US/windows-1251
привет
Привет!
> '?аЁў?в!': [8f e0 a8 a2 a5 e2 21]
exit
----

F:\SO>java -Dfile.encoding=cp866 App2
en_US/cp866
привет
Привет!
> 'Привет!': [8f e0 a8 a2 a5 e2 21]
exit
----

При запуске той же программы в консоли mintty (GitBash), результаты значительно отличались, например, при выборе UTF-8:

  • строки в программе не выводились корректно
  • строка, введённая в сканнере, всегда была представлена в одной и той же кодировке
  • нормальный вывод получался только в Win-1251
nowhereman@nowhere MINGW64 /f/SO
$ java App2
en_US/UTF-8
▒▒▒▒▒▒
Привет!
> '▒▒▒▒▒▒!': [d0 9f d1 80 d0 b8 d0 b2 d0 b5 d1 82 21]
exit
----

nowhereman@nowhere MINGW64 /f/SO
$ java -Dfile.encoding=cp866 App2
en_US/cp866
▒▒▒▒▒▒
Привет!
> '?▒?▒???????▒!': [d0 9f d1 80 d0 b8 d0 b2 d0 b5 d1 82 21]
exit
----

nowhereman@nowhere MINGW64 /f/SO
$ java -Dfile.encoding=windows-1251 App2
en_US/windows-1251
▒▒▒▒▒▒
Привет!
> 'Привет!': [d0 9f d1 80 d0 b8 d0 b2 d0 b5 d1 82 21]
exit
----
→ Ссылка
Автор решения: denis

Разобрался. Вся проблема была из-за моего непонимания того, как это все работает "под капотом". Суть такова: 1). Файл имеет свою кодировку, именно этот момент мы и проговариваем в консоли тогда, когда пишем следующее:

java -Dfile.encoding=UTF-8 App.java

То есть дословно: "открой файл с кодировкой utf-8" 2). Консоль имеет свою кодировку, которую мы и указываем через chcp. Данная кодировка не имеет никакого отношения к открытию файла, но имеет отношение к кодировке вводимых данных, а имеенно здесь можно указать как "windows-1251", так и "cp866"(вопрос с 65001 я так и не решил) 3). После ввода данных они узодят в jvm на scanner, который работает по дефолту с utf-8(если я путаю, то прошу поправить) и здесь уже следует проговорим Scannerу какую кодировку мы ему подсовываем, а подсоовываем мы ему кодировку из консоли. В моем случае windows-1251:

Scanner console = new Scanner(System.in, "Windows-1251");

И получаем результат:

c:\>chcp 1251
Текущая кодовая страница: 1251

c:\>java -Dfile.encoding=UTF-8 App.java
Написано однажды, работает везде
Введите свое имя: Денис
Введенное имя: Денис

Прошу поправить, если я где-то был не точен в своих суждениях

Всем спасибо за помощь

→ Ссылка