Получить Unicode из шестнадцатеричной

Я искал решение своей проблемы в течение нескольких дней, но не могу получить точный ответ, просматривая ранее отвеченные вопросы / блоги / учебные пособия и т. Д. По всему Интернету.

Моя цель - написать программу, которая принимает десятичное число в качестве входных данных, а затем вычисляет шестнадцатеричное число, а также печатает юникод-символ указанного шестнадцатеричного числа (\uXXXX). Моя проблема в том, что я не могу «преобразовать» шестнадцатеричное число в юникод. (Это должно быть записано в следующем формате: \uXXXX)

Пример:

Вход:

122 (= десятичный)

Выход:

Шестнадцатеричный: 7A

Юникод: z | Символ Юникода: строчная латинская буква "z"

Единственное, что мне удалось сделать, это напечатать юникод (\ u007A), но мне нужен символ («z»). Я подумал, что если в юникоде всего 4 цифры/буквы, мне просто нужно будет «скопировать» шестнадцатеричное число в код и заполнить оставшиеся места нулями, и это вроде как сработает, но, как я уже сказал, мне нужен символ, а не код. Так что я пытался и пытался, но я просто не мог получить символ. Насколько я понимаю, если вам нужен символ, вам нужно напечатать его в виде строки. Но при попытке со строкой я получаю сообщение об ошибке «недопустимый выход из юникода».

Это похоже на то, что вы можете печатать только заранее определенные юникоды, а не «случайные», сгенерированные на месте в зависимости от вашего ввода.

Я только пару дней в Java, поэтому извиняюсь, если я что-то пропустил.

Спасибо за чтение.

Мой код:

        int dec;
        int quotient;
        int rest;
        int[]hex = new int[10];
        char[]chars = new char[]{
            'F',
            'E',
            'D',
            'C',
            'B',
            'A'
        };
        String unicode;
// Input Number
        System.out.println("Input decimal number:");
        Scanner input = new Scanner(System.in);
        dec = input.nextInt();
//
// "Converting to hexadecimal
        quotient = dec / 16;           
        rest = dec % 16;
        hex[0] = rest;

        int j = 1;
        while (quotient != 0) {
            rest = quotient % 16;
            quotient = quotient / 16;
            hex[j] = rest;
            j++;
        }
//

        /*if (j == 1) {
            unicode = '\u000';
        }
        if (j == 2) {
            unicode = '\u00';
        }
        if (j == 3) {
            unicode = '\u0';
        }*/

        System.out.println("Your number: " + dec);
        System.out.print("The corresponding Hexadecimal number: ");

        for (int i = j - 1; i >= 0; i--) {
            if (hex[i] > 9) {
                if (j == 1) {
                    unicode = "\u000" + String.valueOf(chars[16 - hex[i] - 1]);
                }
                if (j == 2) {
                    unicode = "\u00" + String.valueOf(chars[16 - hex[i] - 1]);
                }
                if (j == 3) {
                    unicode = "\u0" + String.valueOf(chars[16 - hex[i] - 1]);
                }
                System.out.print(chars[16 - hex[i] - 1]);
            } else {
                if (j == 1) {
                    unicode = "\u000" + Character.valueOf[hex[i]);
                }
                if (j == 2) {
                    unicode = "\u00" + Character.valueOf(hex[i]);
                }
                if (j == 3) {
                    unicode = "\u0" + Character.valueOf(hex[i]);
                }
                System.out.print(hex[i]);
            }
        }

        System.out.println();
        System.out.print("Unicode: " + (unicode));
    }

Это не продвинутый код, я написал его именно так, как рассчитал бы на бумаге. Разделив число на 16, пока я не получу 0, и при этом останется шестнадцатеричный эквивалент. Поэтому я поместил его в цикл while, поскольку я буду делить число n раз, пока не получу 0, условием будет повторять деление до тех пор, пока частное не станет равным нулю. При этом остатки каждого деления будут цифрами/буквами моего шестнадцатеричного числа, поэтому мне нужно их сохранить. Для этого я выбираю целочисленный массив. Остальные (остатки) = hex[j]. Я также бросил переменную в названии «j», чтобы теперь я знал, сколько раз повторяется деление. Так что я мог определить, как долго шестнадцатеричное. В примере это будет 2 буквы/цифры (7A), поэтому j = 2. Затем переменная будет использоваться для определения того, сколько нулей мне нужно, чтобы заполнить юникод. Если у меня есть только 2 буквы/цифры, это означает, что после \u есть 2 пустых места, поэтому мы добавляем два нуля, чтобы получить z вместо \u7A.

Также следующая команда if заменяет любые числа выше 9 символом из массива char выше. В основном так же, как вы бы сделали на бумаге.

Я очень извиняюсь за этот безумно длинный вопрос.


person M0e    schedule 15.10.2019    source источник
comment
Добавление кода, который вы пробовали, может помочь кому-то ответить на ваш вопрос и точно определить, в чем проблема.   -  person Jake Luby    schedule 15.10.2019
comment
(char) dec должен подойти, немного более полный Character.toChars(dec)   -  person user85421    schedule 15.10.2019
comment
Примечание: вы не можете распечатать все кодовые точки Юникода: некоторые из них просто объединяют символы, в этом случае вы должны добавить заполнитель (вы часто видите пунктирный кружок), Другие специальные символы: просто напечатайте имя. (и ищите корейский код)   -  person Giacomo Catenazzi    schedule 16.10.2019


Ответы (2)


Вы можете просто использовать System.out.printf или String.format, чтобы делать то, что вы хотите.

Пример:

int decimal = 122;

System.out.printf("Hexadecimal: %X\n", decimal);
System.out.printf("Unicode: u%04X\n", decimal);
System.out.printf("Latin small letter: %c\n", (char)decimal);

Выход:

Hexadecimal: 7A
Unicode: u007A
Latin small letter: z
person Christos Lytras    schedule 15.10.2019
comment
Большое спасибо, это могло бы сэкономить мне столько времени. К сожалению, раньше я не был таким умным, я рассмотрю ваш ответ, чтобы полностью понять, что делает каждая команда. Еще раз большое спасибо за ваш ответ для начинающих. - person M0e; 15.10.2019
comment
Поэтому я заглянул в блог Formatter (?) здесь Formatter (Oracle Docs) и насколько я понял: printf = format your output | % используется для добавления конверсии | %X форматирует вывод в шестнадцатеричный | %c форматирует вывод в символ Юникода. Единственное, чего я не понимаю, это u% 04X или больше, как это работает. Я полагаю, что u печатается как обычно, но что именно делает 04? Я не смог найти этот 04 на сайте, упомянутом выше. @Христос - person M0e; 15.10.2019
comment
Это формат заполнения нулями. u - это просто символ, который вы хотите напечатать перед дополненной строкой, 04 представляет собой заполнение нулями с 4 нулями. Вы можете выполнить поиск printf нулевого заполнения для получения более подробной информации, например, здесь java2s.com/Tutorial /Java/0120__Разработка/ - person Christos Lytras; 15.10.2019

U+007A — это 3-байтовый указатель кода.

\u007A — это символ UTF-16.

Указатель кода Юникода, символ, иногда преобразуется в два char, и тогда шестнадцатеричные числа не совпадают. Следовательно, лучше всего использовать указатели кода. Поскольку UTF-16 - это просто схема кодирования для двухбайтового представления, где суррогатные пары для 3-байтовых чисел Unicode не содержат / или что-то подобное (старший бит всегда равен 1).

int hex = 0x7A;
hex = Integer.parseUnsignedInt("007A", 16);
char ch = (char) hex;
String stringWith1CodePoint = new String(new int[] { hex }, 0, 1);
int[] codePoints = stringWith1CodePoint.codePoints().toArray();

String s = "????"; // U+1D11E = "\uD834\uDD1E"
person Joop Eggen    schedule 15.10.2019
comment
Большое спасибо за ваш невероятно быстрый ответ. Также спасибо за прояснение для меня вещей, я боюсь, что мои текущие знания по этому вопросу затрудняют мне полное понимание этого. Я посмотрю на это, спасибо. - person M0e; 15.10.2019