Получить Юникод из шестнадцатеричного числа - PullRequest
0 голосов
/ 15 октября 2019

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

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

Пример:

Ввод:

122 (= десятичное число)

Вывод:

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

Unicode: \ u007A |Символ Unicode: Латинская строчная буква "z"

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

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

Я только пару дней на 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. Затем переменная будет использоваться для определения того, сколько 0 мне нужно, чтобы заполнить юникод. Если у меня только 2 буквы / цифры, это означает, что после \ u есть 2 пустых места, поэтому мы добавляем два нуля, чтобы получить \ u007A вместо \ u7A.

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

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

Ответы [ 2 ]

1 голос
/ 15 октября 2019

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

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

Unicodeуказатель кода, символ, иногда преобразуется в два 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"
0 голосов
/ 15 октября 2019

Вы можете просто использовать 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
...